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
findtype(strarg_t * strs,const char * s)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
set_homedir(netpgp_t * netpgp,char * home,const char * subdir,const int quiet)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
l_new(lua_State * L)102 l_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) */
114 static int
l_init(lua_State * L)115 l_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) */
125 static int
l_homedir(lua_State * L)126 l_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
137 static 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) */
146 static int
l_encrypt_file(lua_State * L)147 l_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) */
170 static int
l_decrypt_file(lua_State * L)171 l_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
191 static 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) */
199 static int
l_sign_file(lua_State * L)200 l_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) */
227 static int
l_clearsign_file(lua_State * L)228 l_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) */
252 static int
l_verify_file(lua_State * L)253 l_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) */
269 static int
l_verify_cat_file(lua_State * L)270 l_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) */
288 static int
l_list_packets(lua_State * L)289 l_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) */
305 static int
l_setvar(lua_State * L)306 l_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) */
322 static int
l_getvar(lua_State * L)323 l_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
336 const 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
357 int
luaopen_netpgp(lua_State * L)358 luaopen_netpgp(lua_State *L)
359 {
360 luaL_openlib(L, "netpgp", libluanetpgp, 0);
361 return 1;
362 }
363