xref: /netbsd-src/crypto/external/bsd/netpgp/dist/bindings/lua/glue.c (revision f75f5aae154fcd0572e8889e4fea2a51d67bbf08)
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 
51 int luaopen_netpgp(lua_State *);
52 
53 typedef 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 */
59 static int
60 findtype(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" */
70 static int
71 set_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() */
101 static int
102 l_new(lua_State *L)
103 {
104 	netpgp_t	*netpgp;
105 
106 	netpgp = lua_newuserdata(L, sizeof(*netpgp));
107 	set_homedir(netpgp, getenv("HOME"), "/.gnupg", 1);
108 	netpgp_setvar(netpgp, "hash", DEFAULT_HASH_ALG);
109 	return 1;
110 }
111 
112 /* initialise(netpgp) */
113 static int
114 l_init(lua_State *L)
115 {
116 	netpgp_t	*netpgp;
117 
118 	netpgp = lua_touserdata(L, 1);
119 	lua_pushnumber(L, netpgp_init(netpgp));
120 	return 1;
121 }
122 
123 /* homedir(netpgp, homedir) */
124 static int
125 l_homedir(lua_State *L)
126 {
127 	const char	*home;
128 	netpgp_t	*netpgp;
129 
130 	netpgp = lua_touserdata(L, 1);
131 	home = luaL_checkstring(L, 2);
132 	lua_pushnumber(L, set_homedir(netpgp, __UNCONST(home), NULL, 0));
133 	return 1;
134 }
135 
136 static strarg_t	armourtypes[] = {
137 	{	"armoured",	1	},
138 	{	"armored",	1	},
139 	{	"armour",	1	},
140 	{	"armor",	1	},
141 	{	NULL,		0	}
142 };
143 
144 /* encrypt_file(netpgp, f, output, armour) */
145 static int
146 l_encrypt_file(lua_State *L)
147 {
148 	const char	*output;
149 	const char	*f;
150 	netpgp_t	*netpgp;
151 	int		 armour;
152 	int		 ret;
153 
154 	netpgp = lua_touserdata(L, 1);
155 	netpgp_setvar(netpgp, "need userid", "1");
156 	f = luaL_checkstring(L, 2);
157 	output = luaL_checkstring(L, 3);
158 	if (*output == 0x0) {
159 		output = NULL;
160 	}
161 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
162 	ret = netpgp_encrypt_file(netpgp, netpgp_getvar(netpgp, "userid"),
163 				f, __UNCONST("a.gpg"), armour);
164 	lua_pushnumber(L, ret);
165 	return 1;
166 }
167 
168 /* decrypt_file(netpgp, f, output, armour) */
169 static int
170 l_decrypt_file(lua_State *L)
171 {
172 	const char	*output;
173 	const char	*f;
174 	netpgp_t	*netpgp;
175 	int		 armour;
176 	int		 ret;
177 
178 	netpgp = lua_touserdata(L, 1);
179 	f = luaL_checkstring(L, 2);
180 	output = luaL_checkstring(L, 3);
181 	if (*output == 0x0) {
182 		output = NULL;
183 	}
184 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
185 	ret = netpgp_decrypt_file(netpgp, f, __UNCONST(output), armour);
186 	lua_pushnumber(L, ret);
187 	return 1;
188 }
189 
190 static strarg_t	detachtypes[] = {
191 	{	"detached",	1	},
192 	{	"separate",	1	},
193 	{	"detach",	1	},
194 	{	NULL,		0	}
195 };
196 
197 /* sign_file(netpgp, f, output, armour, detached) */
198 static int
199 l_sign_file(lua_State *L)
200 {
201 	const char	*output;
202 	const char	*f;
203 	const int	 binary = 0;
204 	netpgp_t	*netpgp;
205 	int		 detached;
206 	int		 armour;
207 	int		 ret;
208 
209 	netpgp = lua_touserdata(L, 1);
210 	netpgp_setvar(netpgp, "need userid", "1");
211 	f = luaL_checkstring(L, 2);
212 	output = luaL_checkstring(L, 3);
213 	if (*output == 0x0) {
214 		output = NULL;
215 	}
216 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
217 	detached = findtype(detachtypes, luaL_checkstring(L, 5));
218 	ret = netpgp_sign_file(netpgp, netpgp_getvar(netpgp, "userid"),
219 				f, __UNCONST(output), armour, binary,
220 				detached);
221 	lua_pushnumber(L, ret);
222 	return 1;
223 }
224 
225 /* clearsign_file(netpgp, f, output, armour, detached) */
226 static int
227 l_clearsign_file(lua_State *L)
228 {
229 	const char	*output;
230 	const char	*f;
231 	const int	 cleartext = 1;
232 	netpgp_t	*netpgp;
233 	int		 detached;
234 	int		 armour;
235 	int		 ret;
236 
237 	netpgp = lua_touserdata(L, 1);
238 	netpgp_setvar(netpgp, "need userid", "1");
239 	f = luaL_checkstring(L, 2);
240 	output = luaL_checkstring(L, 3);
241 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
242 	detached = findtype(detachtypes, luaL_checkstring(L, 5));
243 	ret = netpgp_sign_file(netpgp, netpgp_getvar(netpgp, "userid"),
244 				f, __UNCONST(output), armour, cleartext,
245 				detached);
246 	lua_pushnumber(L, ret);
247 	return 1;
248 }
249 
250 /* verify_file(netpgp, f, armour) */
251 static int
252 l_verify_file(lua_State *L)
253 {
254 	const char	*f;
255 	netpgp_t	*netpgp;
256 	int		 armour;
257 	int		 ret;
258 
259 	netpgp = lua_touserdata(L, 1);
260 	f = luaL_checkstring(L, 2);
261 	armour = findtype(armourtypes, luaL_checkstring(L, 3));
262 	ret = netpgp_verify_file(netpgp, f, NULL, armour);
263 	lua_pushnumber(L, ret);
264 	return 1;
265 }
266 
267 /* verify_cat_file(netpgp, f, output, armour) */
268 static int
269 l_verify_cat_file(lua_State *L)
270 {
271 	const char	*output;
272 	const char	*f;
273 	netpgp_t	*netpgp;
274 	int		 armour;
275 	int		 ret;
276 
277 	netpgp = lua_touserdata(L, 1);
278 	f = luaL_checkstring(L, 2);
279 	output = luaL_checkstring(L, 3);
280 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
281 	ret = netpgp_verify_file(netpgp, f, output, armour);
282 	lua_pushnumber(L, ret);
283 	return 1;
284 }
285 
286 /* list_packets(netpgp, f, armour) */
287 static int
288 l_list_packets(lua_State *L)
289 {
290 	const char	*f;
291 	netpgp_t	*netpgp;
292 	int		 armour;
293 	int		 ret;
294 
295 	netpgp = lua_touserdata(L, 1);
296 	f = luaL_checkstring(L, 2);
297 	armour = findtype(armourtypes, luaL_checkstring(L, 3));
298 	ret = netpgp_list_packets(netpgp, __UNCONST(f), armour, NULL);
299 	lua_pushnumber(L, ret);
300 	return 1;
301 }
302 
303 /* setvar(netpgp, name, value) */
304 static int
305 l_setvar(lua_State *L)
306 {
307 	const char	*name;
308 	const char	*value;
309 	netpgp_t	*netpgp;
310 	int		 ret;
311 
312 	netpgp = lua_touserdata(L, 1);
313 	name = luaL_checkstring(L, 2);
314 	value = luaL_checkstring(L, 3);
315 	ret = netpgp_setvar(netpgp, name, value);
316 	lua_pushnumber(L, ret);
317 	return 1;
318 }
319 
320 /* getvar(netpgp, name, value) */
321 static int
322 l_getvar(lua_State *L)
323 {
324 	const char	*name;
325 	const char	*ret;
326 	netpgp_t	*netpgp;
327 
328 	netpgp = lua_touserdata(L, 1);
329 	name = luaL_checkstring(L, 2);
330 	ret = netpgp_getvar(netpgp, name);
331 	lua_pushstring(L, ret);
332 	return 1;
333 }
334 
335 const struct luaL_reg libnetpgp[] = {
336 	{ "new",		l_new },
337 	{ "init",		l_init },
338 
339 	{ "encrypt_file",	l_encrypt_file },
340 	{ "decrypt_file",	l_decrypt_file },
341 	{ "sign_file",		l_sign_file },
342 	{ "clearsign_file",	l_clearsign_file },
343 	{ "verify_file",	l_verify_file },
344 	{ "verify_cat_file",	l_verify_cat_file },
345 
346 	{ "list_packets",	l_list_packets },
347 
348 	{ "getvar",		l_getvar },
349 	{ "setvar",		l_setvar },
350 
351 	{ "homedir",		l_homedir },
352 
353 	{ NULL,			NULL }
354 };
355 
356 int
357 luaopen_netpgp(lua_State *L)
358 {
359 	luaL_openlib(L, "netpgp", libnetpgp, 0);
360 	return 1;
361 }
362