glue.c revision 1.2
1/*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@netbsd.org)
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29#include <sys/types.h>
30#include <sys/param.h>
31#include <sys/stat.h>
32
33#include <inttypes.h>
34#include <netpgp.h>
35#include <string.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <unistd.h>
39
40#define LUA_LIB
41#include <lua.h>
42#include <lauxlib.h>
43#include <lualib.h>
44
45#ifndef __UNCONST
46#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
47#endif /* !__UNCONST */
48
49#define DEFAULT_HASH_ALG        "SHA256"
50
51int luaopen_netpgp(lua_State *);
52
53typedef struct strarg_t {
54	const char	*s;	/* string */
55	const int	 n;	/* corresponding int value */
56} strarg_t;
57
58/* map a string onto an int */
59static int
60findtype(strarg_t *strs, const char *s)
61{
62	strarg_t	*sp;
63
64	for (sp = strs ; sp->s && strcasecmp(sp->s, s) != 0 ; sp++) {
65	}
66	return sp->n;
67}
68
69/* set the home directory value to "home/subdir" */
70static int
71set_homedir(netpgp_t *netpgp, char *home, const char *subdir, const int quiet)
72{
73	struct stat	st;
74	char		d[MAXPATHLEN];
75
76	if (home == NULL) {
77		if (!quiet) {
78			(void) fprintf(stderr, "NULL HOME directory\n");
79		}
80		return 0;
81	}
82	(void) snprintf(d, sizeof(d), "%s%s", home, (subdir) ? subdir : "");
83	if (stat(d, &st) == 0) {
84		if ((st.st_mode & S_IFMT) == S_IFDIR) {
85			netpgp_setvar(netpgp, "homedir", d);
86			return 1;
87		}
88		(void) fprintf(stderr, "netpgp: homedir \"%s\" is not a dir\n",
89					d);
90		return 0;
91	}
92	if (!quiet) {
93		(void) fprintf(stderr,
94			"netpgp: warning homedir \"%s\" not found\n", d);
95	}
96	return 1;
97}
98
99
100/* init() */
101static int
102l_new(lua_State *L)
103{
104	netpgp_t	*netpgp;
105
106	netpgp = lua_newuserdata(L, sizeof(*netpgp));
107	(void) memset(netpgp, 0x0, sizeof(*netpgp));
108	set_homedir(netpgp, getenv("HOME"), "/.gnupg", 1);
109	netpgp_setvar(netpgp, "hash", DEFAULT_HASH_ALG);
110	return 1;
111}
112
113/* initialise(netpgp) */
114static int
115l_init(lua_State *L)
116{
117	netpgp_t	*netpgp;
118
119	netpgp = lua_touserdata(L, 1);
120	lua_pushnumber(L, netpgp_init(netpgp));
121	return 1;
122}
123
124/* homedir(netpgp, homedir) */
125static int
126l_homedir(lua_State *L)
127{
128	const char	*home;
129	netpgp_t	*netpgp;
130
131	netpgp = lua_touserdata(L, 1);
132	home = luaL_checkstring(L, 2);
133	lua_pushnumber(L, set_homedir(netpgp, __UNCONST(home), NULL, 0));
134	return 1;
135}
136
137static strarg_t	armourtypes[] = {
138	{	"armoured",	1	},
139	{	"armored",	1	},
140	{	"armour",	1	},
141	{	"armor",	1	},
142	{	NULL,		0	}
143};
144
145/* encrypt_file(netpgp, f, output, armour) */
146static int
147l_encrypt_file(lua_State *L)
148{
149	const char	*output;
150	const char	*f;
151	netpgp_t	*netpgp;
152	int		 armour;
153	int		 ret;
154
155	netpgp = lua_touserdata(L, 1);
156	netpgp_setvar(netpgp, "need userid", "1");
157	f = luaL_checkstring(L, 2);
158	output = luaL_checkstring(L, 3);
159	if (*output == 0x0) {
160		output = NULL;
161	}
162	armour = findtype(armourtypes, luaL_checkstring(L, 4));
163	ret = netpgp_encrypt_file(netpgp, netpgp_getvar(netpgp, "userid"),
164				f, __UNCONST("a.gpg"), armour);
165	lua_pushnumber(L, ret);
166	return 1;
167}
168
169/* decrypt_file(netpgp, f, output, armour) */
170static int
171l_decrypt_file(lua_State *L)
172{
173	const char	*output;
174	const char	*f;
175	netpgp_t	*netpgp;
176	int		 armour;
177	int		 ret;
178
179	netpgp = lua_touserdata(L, 1);
180	f = luaL_checkstring(L, 2);
181	output = luaL_checkstring(L, 3);
182	if (*output == 0x0) {
183		output = NULL;
184	}
185	armour = findtype(armourtypes, luaL_checkstring(L, 4));
186	ret = netpgp_decrypt_file(netpgp, f, __UNCONST(output), armour);
187	lua_pushnumber(L, ret);
188	return 1;
189}
190
191static strarg_t	detachtypes[] = {
192	{	"detached",	1	},
193	{	"separate",	1	},
194	{	"detach",	1	},
195	{	NULL,		0	}
196};
197
198/* sign_file(netpgp, f, output, armour, detached) */
199static int
200l_sign_file(lua_State *L)
201{
202	const char	*output;
203	const char	*f;
204	const int	 binary = 0;
205	netpgp_t	*netpgp;
206	int		 detached;
207	int		 armour;
208	int		 ret;
209
210	netpgp = lua_touserdata(L, 1);
211	netpgp_setvar(netpgp, "need userid", "1");
212	f = luaL_checkstring(L, 2);
213	output = luaL_checkstring(L, 3);
214	if (*output == 0x0) {
215		output = NULL;
216	}
217	armour = findtype(armourtypes, luaL_checkstring(L, 4));
218	detached = findtype(detachtypes, luaL_checkstring(L, 5));
219	ret = netpgp_sign_file(netpgp, netpgp_getvar(netpgp, "userid"),
220				f, __UNCONST(output), armour, binary,
221				detached);
222	lua_pushnumber(L, ret);
223	return 1;
224}
225
226/* clearsign_file(netpgp, f, output, armour, detached) */
227static int
228l_clearsign_file(lua_State *L)
229{
230	const char	*output;
231	const char	*f;
232	const int	 cleartext = 1;
233	netpgp_t	*netpgp;
234	int		 detached;
235	int		 armour;
236	int		 ret;
237
238	netpgp = lua_touserdata(L, 1);
239	netpgp_setvar(netpgp, "need userid", "1");
240	f = luaL_checkstring(L, 2);
241	output = luaL_checkstring(L, 3);
242	armour = findtype(armourtypes, luaL_checkstring(L, 4));
243	detached = findtype(detachtypes, luaL_checkstring(L, 5));
244	ret = netpgp_sign_file(netpgp, netpgp_getvar(netpgp, "userid"),
245				f, __UNCONST(output), armour, cleartext,
246				detached);
247	lua_pushnumber(L, ret);
248	return 1;
249}
250
251/* verify_file(netpgp, f, armour) */
252static int
253l_verify_file(lua_State *L)
254{
255	const char	*f;
256	netpgp_t	*netpgp;
257	int		 armour;
258	int		 ret;
259
260	netpgp = lua_touserdata(L, 1);
261	f = luaL_checkstring(L, 2);
262	armour = findtype(armourtypes, luaL_checkstring(L, 3));
263	ret = netpgp_verify_file(netpgp, f, NULL, armour);
264	lua_pushnumber(L, ret);
265	return 1;
266}
267
268/* verify_cat_file(netpgp, f, output, armour) */
269static int
270l_verify_cat_file(lua_State *L)
271{
272	const char	*output;
273	const char	*f;
274	netpgp_t	*netpgp;
275	int		 armour;
276	int		 ret;
277
278	netpgp = lua_touserdata(L, 1);
279	f = luaL_checkstring(L, 2);
280	output = luaL_checkstring(L, 3);
281	armour = findtype(armourtypes, luaL_checkstring(L, 4));
282	ret = netpgp_verify_file(netpgp, f, output, armour);
283	lua_pushnumber(L, ret);
284	return 1;
285}
286
287/* list_packets(netpgp, f, armour) */
288static int
289l_list_packets(lua_State *L)
290{
291	const char	*f;
292	netpgp_t	*netpgp;
293	int		 armour;
294	int		 ret;
295
296	netpgp = lua_touserdata(L, 1);
297	f = luaL_checkstring(L, 2);
298	armour = findtype(armourtypes, luaL_checkstring(L, 3));
299	ret = netpgp_list_packets(netpgp, __UNCONST(f), armour, NULL);
300	lua_pushnumber(L, ret);
301	return 1;
302}
303
304/* setvar(netpgp, name, value) */
305static int
306l_setvar(lua_State *L)
307{
308	const char	*name;
309	const char	*value;
310	netpgp_t	*netpgp;
311	int		 ret;
312
313	netpgp = lua_touserdata(L, 1);
314	name = luaL_checkstring(L, 2);
315	value = luaL_checkstring(L, 3);
316	ret = netpgp_setvar(netpgp, name, value);
317	lua_pushnumber(L, ret);
318	return 1;
319}
320
321/* getvar(netpgp, name, value) */
322static int
323l_getvar(lua_State *L)
324{
325	const char	*name;
326	const char	*ret;
327	netpgp_t	*netpgp;
328
329	netpgp = lua_touserdata(L, 1);
330	name = luaL_checkstring(L, 2);
331	ret = netpgp_getvar(netpgp, name);
332	lua_pushstring(L, ret);
333	return 1;
334}
335
336const struct luaL_reg libluanetpgp[] = {
337	{ "new",		l_new },
338	{ "init",		l_init },
339
340	{ "encrypt_file",	l_encrypt_file },
341	{ "decrypt_file",	l_decrypt_file },
342	{ "sign_file",		l_sign_file },
343	{ "clearsign_file",	l_clearsign_file },
344	{ "verify_file",	l_verify_file },
345	{ "verify_cat_file",	l_verify_cat_file },
346
347	{ "list_packets",	l_list_packets },
348
349	{ "getvar",		l_getvar },
350	{ "setvar",		l_setvar },
351
352	{ "homedir",		l_homedir },
353
354	{ NULL,			NULL }
355};
356
357int
358luaopen_netpgp(lua_State *L)
359{
360	luaL_openlib(L, "netpgp", libluanetpgp, 0);
361	return 1;
362}
363