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