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