xref: /netbsd-src/crypto/external/bsd/netpgp/dist/bindings/lua/glue.c (revision c38e7cc395b1472a774ff828e46123de44c628e9)
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 #define LUA_USE_APICHECK
42 #include <lua.h>
43 #include <lauxlib.h>
44 #include <lualib.h>
45 
46 #ifndef __UNCONST
47 #define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
48 #endif /* !__UNCONST */
49 
50 #define DEFAULT_HASH_ALG        "SHA256"
51 
52 int luaopen_netpgp(lua_State *);
53 
54 typedef struct strarg_t {
55 	const char	*s;	/* string */
56 	const int	 n;	/* corresponding int value */
57 } strarg_t;
58 
59 /* map a string onto an int */
60 static int
61 findtype(strarg_t *strs, const char *s)
62 {
63 	strarg_t	*sp;
64 
65 	for (sp = strs ; sp->s && strcasecmp(sp->s, s) != 0 ; sp++) {
66 	}
67 	return sp->n;
68 }
69 
70 /* set the home directory value to "home/subdir" */
71 static int
72 set_homedir(netpgp_t *netpgp, char *home, const char *subdir, const int quiet)
73 {
74 	struct stat	st;
75 	char		d[MAXPATHLEN];
76 
77 	if (home == NULL) {
78 		if (!quiet) {
79 			(void) fprintf(stderr, "NULL HOME directory\n");
80 		}
81 		return 0;
82 	}
83 	(void) snprintf(d, sizeof(d), "%s%s", home, (subdir) ? subdir : "");
84 	if (stat(d, &st) == 0) {
85 		if ((st.st_mode & S_IFMT) == S_IFDIR) {
86 			netpgp_setvar(netpgp, "homedir", d);
87 			return 1;
88 		}
89 		(void) fprintf(stderr, "netpgp: homedir \"%s\" is not a dir\n",
90 					d);
91 		return 0;
92 	}
93 	if (!quiet) {
94 		(void) fprintf(stderr,
95 			"netpgp: warning homedir \"%s\" not found\n", d);
96 	}
97 	return 1;
98 }
99 
100 
101 /* init() */
102 static int
103 l_new(lua_State *L)
104 {
105 	netpgp_t	*netpgp;
106 
107 	netpgp = lua_newuserdata(L, sizeof(*netpgp));
108 	(void) memset(netpgp, 0x0, sizeof(*netpgp));
109 	set_homedir(netpgp, getenv("HOME"), "/.gnupg", 1);
110 	netpgp_setvar(netpgp, "hash", DEFAULT_HASH_ALG);
111 	return 1;
112 }
113 
114 /* initialise(netpgp) */
115 static int
116 l_init(lua_State *L)
117 {
118 	netpgp_t	*netpgp;
119 
120 	netpgp = lua_touserdata(L, 1);
121 	lua_pushnumber(L, netpgp_init(netpgp));
122 	return 1;
123 }
124 
125 /* homedir(netpgp, homedir) */
126 static int
127 l_homedir(lua_State *L)
128 {
129 	const char	*home;
130 	netpgp_t	*netpgp;
131 
132 	netpgp = lua_touserdata(L, 1);
133 	home = luaL_checkstring(L, 2);
134 	lua_pushnumber(L, set_homedir(netpgp, __UNCONST(home), NULL, 0));
135 	return 1;
136 }
137 
138 static strarg_t	armourtypes[] = {
139 	{	"armoured",	1	},
140 	{	"armored",	1	},
141 	{	"armour",	1	},
142 	{	"armor",	1	},
143 	{	NULL,		0	}
144 };
145 
146 /* encrypt_file(netpgp, f, output, armour) */
147 static int
148 l_encrypt_file(lua_State *L)
149 {
150 	const char	*output;
151 	const char	*f;
152 	netpgp_t	*netpgp;
153 	int		 armour;
154 	int		 ret;
155 
156 	netpgp = lua_touserdata(L, 1);
157 	netpgp_setvar(netpgp, "need userid", "1");
158 	f = luaL_checkstring(L, 2);
159 	output = luaL_checkstring(L, 3);
160 	if (*output == 0x0) {
161 		output = NULL;
162 	}
163 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
164 	ret = netpgp_encrypt_file(netpgp, netpgp_getvar(netpgp, "userid"),
165 				f, __UNCONST(output), armour);
166 	lua_pushnumber(L, ret);
167 	return 1;
168 }
169 
170 /* decrypt_file(netpgp, f, output, armour) */
171 static int
172 l_decrypt_file(lua_State *L)
173 {
174 	const char	*output;
175 	const char	*f;
176 	netpgp_t	*netpgp;
177 	int		 armour;
178 	int		 ret;
179 
180 	netpgp = lua_touserdata(L, 1);
181 	f = luaL_checkstring(L, 2);
182 	output = luaL_checkstring(L, 3);
183 	if (*output == 0x0) {
184 		output = NULL;
185 	}
186 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
187 	ret = netpgp_decrypt_file(netpgp, f, __UNCONST(output), armour);
188 	lua_pushnumber(L, ret);
189 	return 1;
190 }
191 
192 static strarg_t	detachtypes[] = {
193 	{	"detached",	1	},
194 	{	"separate",	1	},
195 	{	"detach",	1	},
196 	{	NULL,		0	}
197 };
198 
199 /* sign_file(netpgp, f, output, armour, detached) */
200 static int
201 l_sign_file(lua_State *L)
202 {
203 	const char	*output;
204 	const char	*f;
205 	const int	 binary = 0;
206 	netpgp_t	*netpgp;
207 	int		 detached;
208 	int		 armour;
209 	int		 ret;
210 
211 	netpgp = lua_touserdata(L, 1);
212 	netpgp_setvar(netpgp, "need userid", "1");
213 	f = luaL_checkstring(L, 2);
214 	output = luaL_checkstring(L, 3);
215 	if (*output == 0x0) {
216 		output = NULL;
217 	}
218 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
219 	detached = findtype(detachtypes, luaL_checkstring(L, 5));
220 	ret = netpgp_sign_file(netpgp, netpgp_getvar(netpgp, "userid"),
221 				f, __UNCONST(output), armour, binary,
222 				detached);
223 	lua_pushnumber(L, ret);
224 	return 1;
225 }
226 
227 /* clearsign_file(netpgp, f, output, armour, detached) */
228 static int
229 l_clearsign_file(lua_State *L)
230 {
231 	const char	*output;
232 	const char	*f;
233 	const int	 cleartext = 1;
234 	netpgp_t	*netpgp;
235 	int		 detached;
236 	int		 armour;
237 	int		 ret;
238 
239 	netpgp = lua_touserdata(L, 1);
240 	netpgp_setvar(netpgp, "need userid", "1");
241 	f = luaL_checkstring(L, 2);
242 	output = luaL_checkstring(L, 3);
243 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
244 	detached = findtype(detachtypes, luaL_checkstring(L, 5));
245 	ret = netpgp_sign_file(netpgp, netpgp_getvar(netpgp, "userid"),
246 				f, __UNCONST(output), armour, cleartext,
247 				detached);
248 	lua_pushnumber(L, ret);
249 	return 1;
250 }
251 
252 /* verify_file(netpgp, f, armour) */
253 static int
254 l_verify_file(lua_State *L)
255 {
256 	const char	*f;
257 	netpgp_t	*netpgp;
258 	int		 armour;
259 	int		 ret;
260 
261 	netpgp = lua_touserdata(L, 1);
262 	f = luaL_checkstring(L, 2);
263 	armour = findtype(armourtypes, luaL_checkstring(L, 3));
264 	ret = netpgp_verify_file(netpgp, f, NULL, armour);
265 	lua_pushnumber(L, ret);
266 	return 1;
267 }
268 
269 /* verify_cat_file(netpgp, f, output, armour) */
270 static int
271 l_verify_cat_file(lua_State *L)
272 {
273 	const char	*output;
274 	const char	*f;
275 	netpgp_t	*netpgp;
276 	int		 armour;
277 	int		 ret;
278 
279 	netpgp = lua_touserdata(L, 1);
280 	f = luaL_checkstring(L, 2);
281 	output = luaL_checkstring(L, 3);
282 	armour = findtype(armourtypes, luaL_checkstring(L, 4));
283 	ret = netpgp_verify_file(netpgp, f, output, armour);
284 	lua_pushnumber(L, ret);
285 	return 1;
286 }
287 
288 /* list_packets(netpgp, f, armour) */
289 static int
290 l_list_packets(lua_State *L)
291 {
292 	const char	*f;
293 	netpgp_t	*netpgp;
294 	int		 armour;
295 	int		 ret;
296 
297 	netpgp = lua_touserdata(L, 1);
298 	f = luaL_checkstring(L, 2);
299 	armour = findtype(armourtypes, luaL_checkstring(L, 3));
300 	ret = netpgp_list_packets(netpgp, __UNCONST(f), armour, NULL);
301 	lua_pushnumber(L, ret);
302 	return 1;
303 }
304 
305 /* setvar(netpgp, name, value) */
306 static int
307 l_setvar(lua_State *L)
308 {
309 	const char	*name;
310 	const char	*value;
311 	netpgp_t	*netpgp;
312 	int		 ret;
313 
314 	netpgp = lua_touserdata(L, 1);
315 	name = luaL_checkstring(L, 2);
316 	value = luaL_checkstring(L, 3);
317 	ret = netpgp_setvar(netpgp, name, value);
318 	lua_pushnumber(L, ret);
319 	return 1;
320 }
321 
322 /* getvar(netpgp, name, value) */
323 static int
324 l_getvar(lua_State *L)
325 {
326 	const char	*name;
327 	const char	*ret;
328 	netpgp_t	*netpgp;
329 
330 	netpgp = lua_touserdata(L, 1);
331 	name = luaL_checkstring(L, 2);
332 	ret = netpgp_getvar(netpgp, name);
333 	lua_pushstring(L, ret);
334 	return 1;
335 }
336 
337 const struct luaL_Reg libluanetpgp[] = {
338 	{ "new",		l_new },
339 	{ "init",		l_init },
340 
341 	{ "encrypt_file",	l_encrypt_file },
342 	{ "decrypt_file",	l_decrypt_file },
343 	{ "sign_file",		l_sign_file },
344 	{ "clearsign_file",	l_clearsign_file },
345 	{ "verify_file",	l_verify_file },
346 	{ "verify_cat_file",	l_verify_cat_file },
347 
348 	{ "list_packets",	l_list_packets },
349 
350 	{ "getvar",		l_getvar },
351 	{ "setvar",		l_setvar },
352 
353 	{ "homedir",		l_homedir },
354 
355 	{ NULL,			NULL }
356 };
357 
358 int
359 luaopen_netpgp(lua_State *L)
360 {
361 #if LUA_VERSION_NUM >= 502
362 	luaL_newlib(L, libluanetpgp);
363 #else
364 	luaL_register(L, "netpgp", libluanetpgp);
365 #endif
366 	return 1;
367 }
368