Back to index

opendkim  2.6.6
opendkim-lua.c
Go to the documentation of this file.
00001 /*
00002 **  Copyright (c) 2009-2012, The OpenDKIM Project.  All rights reserved.
00003 **
00004 **  $Id: opendkim-lua.c,v 1.20 2010/09/14 18:23:38 cm-msk Exp $
00005 */
00006 
00007 #ifndef lint
00008 static char opendkim_lua_c_id[] = "@(#)$Id: opendkim-lua.c,v 1.20 2010/09/14 18:23:38 cm-msk Exp $";
00009 #endif /* !lint */
00010 
00011 #include "build-config.h"
00012 
00013 #ifdef USE_LUA
00014 
00015 /* system includes */
00016 #include <sys/types.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <stdio.h>
00020 #include <assert.h>
00021 
00022 /* Lua includes */
00023 #include <lua.h>
00024 #include <lualib.h>
00025 #include <lauxlib.h>
00026 
00027 /* libopendkim includes */
00028 #include <dkim.h>
00029 
00030 /* opendkim includes */
00031 #define DKIMF_LUA_PROTOTYPES
00032 #define DKIMF_MILTER_PROTOTYPES
00033 #include "opendkim-lua.h"
00034 #include "opendkim-db.h"
00035 #include "opendkim.h"
00036 
00037 /* local data types */
00038 struct dkimf_lua_io
00039 {
00040        _Bool         lua_io_done;
00041        const char *  lua_io_script;
00042        size_t        lua_io_len;
00043        size_t        lua_io_alloc;
00044 };
00045 
00046 #if LUA_VERSION_NUM == 502
00047 # define ODKIM_PREFIX       "odkim."
00048 #else /* LUA_VERSION_NUM == 502 */
00049 # define ODKIM_PREFIX       ""
00050 #endif /* LUA_VERSION_NUM == 502 */
00051 
00052 #ifdef DKIMF_LUA_CONTEXT_HOOKS
00053 /* libraries */
00054 static const luaL_Reg dkimf_lua_lib_setup[] =
00055 {
00056        { ODKIM_PREFIX "check_popauth",           dkimf_xs_popauth     },
00057        { ODKIM_PREFIX "db_check",         dkimf_xs_dbquery     },
00058        { ODKIM_PREFIX "db_close",         dkimf_xs_dbclose     },
00059        { ODKIM_PREFIX "db_open",          dkimf_xs_dbopen             },
00060 # ifdef _FFR_LUA_GLOBALS
00061        { ODKIM_PREFIX "export",           dkimf_xs_export             },
00062 # endif /* _FFR_LUA_GLOBALS */
00063        { ODKIM_PREFIX "get_clienthost",   dkimf_xs_clienthost  },
00064        { ODKIM_PREFIX "get_clientip",            dkimf_xs_clientip    },
00065        { ODKIM_PREFIX "get_dbhandle",            dkimf_xs_dbhandle    },
00066        { ODKIM_PREFIX "get_envfrom",             dkimf_xs_getenvfrom  },
00067        { ODKIM_PREFIX "get_fromdomain",   dkimf_xs_fromdomain  },
00068        { ODKIM_PREFIX "get_header",              dkimf_xs_getheader   },
00069        { ODKIM_PREFIX "get_mtasymbol",           dkimf_xs_getsymval   },
00070        { ODKIM_PREFIX "get_rcpt",         dkimf_xs_rcpt        },
00071        { ODKIM_PREFIX "get_rcptarray",           dkimf_xs_rcptarray   },
00072        { ODKIM_PREFIX "internal_ip",             dkimf_xs_internalip  },
00073        { ODKIM_PREFIX "log",                     dkimf_xs_log         },
00074        { ODKIM_PREFIX "rcpt_count",              dkimf_xs_rcptcount   },
00075        { ODKIM_PREFIX "replace_header",   dkimf_xs_replaceheader      },
00076        { ODKIM_PREFIX "resign",           dkimf_xs_resign             },
00077        { ODKIM_PREFIX "set_result",              dkimf_xs_setresult   },
00078        { ODKIM_PREFIX "sign",                    dkimf_xs_requestsig  },
00079 #ifdef _FFR_REPUTATION
00080        { ODKIM_PREFIX "spam",                    dkimf_xs_spam        },
00081 #endif /* _FFR_REPUTATION */
00082        { ODKIM_PREFIX "use_ltag",         dkimf_xs_setpartial  },
00083        { ODKIM_PREFIX "verify",           dkimf_xs_verify             },
00084        { ODKIM_PREFIX "xtag",                    dkimf_xs_xtag        },
00085        { NULL,                                   NULL                 }
00086 };
00087 
00088 static const luaL_Reg dkimf_lua_lib_screen[] =
00089 {
00090        { ODKIM_PREFIX "db_check",         dkimf_xs_dbquery     },
00091        { ODKIM_PREFIX "db_close",         dkimf_xs_dbclose     },
00092        { ODKIM_PREFIX "db_open",          dkimf_xs_dbopen             },
00093 # ifdef _FFR_LUA_GLOBALS
00094        { ODKIM_PREFIX "export",           dkimf_xs_export             },
00095 # endif /* _FFR_LUA_GLOBALS */
00096        { ODKIM_PREFIX "get_dbhandle",            dkimf_xs_dbhandle    },
00097        { ODKIM_PREFIX "get_envfrom",             dkimf_xs_getenvfrom  },
00098        { ODKIM_PREFIX "get_fromdomain",   dkimf_xs_fromdomain  },
00099        { ODKIM_PREFIX "get_header",              dkimf_xs_getheader   },
00100        { ODKIM_PREFIX "get_mtasymbol",           dkimf_xs_getsymval   },
00101        { ODKIM_PREFIX "get_rcpt",         dkimf_xs_rcpt        },
00102        { ODKIM_PREFIX "get_rcptarray",           dkimf_xs_rcptarray   },
00103        { ODKIM_PREFIX "get_sigarray",            dkimf_xs_getsigarray },
00104        { ODKIM_PREFIX "get_sigcount",            dkimf_xs_getsigcount },
00105        { ODKIM_PREFIX "get_sighandle",           dkimf_xs_getsighandle       },
00106        { ODKIM_PREFIX "log",                     dkimf_xs_log         },
00107        { ODKIM_PREFIX "parse_field",             dkimf_xs_parsefield  },
00108        { ODKIM_PREFIX "rcpt_count",              dkimf_xs_rcptcount   },
00109        { ODKIM_PREFIX "sig_getdomain",           dkimf_xs_getsigdomain       },
00110        { ODKIM_PREFIX "sig_getidentity",  dkimf_xs_getsigidentity     },
00111        { ODKIM_PREFIX "sig_ignore",              dkimf_xs_sigignore   },
00112 #ifdef _FFR_REPUTATION
00113        { ODKIM_PREFIX "spam",                    dkimf_xs_spam        },
00114 #endif /* _FFR_REPUTATION */
00115        { NULL,                                   NULL                 }
00116 };
00117 
00118 # ifdef _FFR_STATSEXT
00119 static const luaL_Reg dkimf_lua_lib_stats[] =
00120 {
00121 #  ifdef _FFR_LUA_GLOBALS
00122        { ODKIM_PREFIX "export",           dkimf_xs_export             },
00123 #  endif /* _FFR_LUA_GLOBALS */
00124        { ODKIM_PREFIX "get_envfrom",             dkimf_xs_getenvfrom  },
00125        { ODKIM_PREFIX "get_header",              dkimf_xs_getheader   },
00126        { ODKIM_PREFIX "get_mtasymbol",           dkimf_xs_getsymval   },
00127        { ODKIM_PREFIX "get_policy",              dkimf_xs_getpolicy   },
00128        { ODKIM_PREFIX "get_rcpt",         dkimf_xs_rcpt        },
00129        { ODKIM_PREFIX "get_rcptarray",           dkimf_xs_rcptarray   },
00130        { ODKIM_PREFIX "get_reputation",   dkimf_xs_getreputation      },
00131        { ODKIM_PREFIX "get_sigarray",            dkimf_xs_getsigarray },
00132        { ODKIM_PREFIX "get_sigcount",            dkimf_xs_getsigcount },
00133        { ODKIM_PREFIX "get_sighandle",           dkimf_xs_getsighandle       },
00134        { ODKIM_PREFIX "log",                     dkimf_xs_log         },
00135        { ODKIM_PREFIX "parse_field",             dkimf_xs_parsefield  },
00136 #  ifdef _FFR_LUA_GLOBALS
00137 #   ifdef _FFR_RBL
00138        { ODKIM_PREFIX "rbl_check",        dkimf_xs_rblcheck    },
00139 #   endif /* _FFR_RBL */
00140 #  endif /* _FFR_LUA_GLOBALS */
00141        { ODKIM_PREFIX "rcpt_count",              dkimf_xs_rcptcount   },
00142        { ODKIM_PREFIX "sig_bhresult",            dkimf_xs_sigbhresult },
00143        { ODKIM_PREFIX "sig_bodylength",   dkimf_xs_bodylength  },
00144        { ODKIM_PREFIX "sig_canonlength",  dkimf_xs_canonlength },
00145        { ODKIM_PREFIX "sig_getdomain",           dkimf_xs_getsigdomain       },
00146        { ODKIM_PREFIX "sig_getidentity",  dkimf_xs_getsigidentity     },
00147        { ODKIM_PREFIX "sig_result",              dkimf_xs_sigresult   },
00148        { ODKIM_PREFIX "stats",                   dkimf_xs_statsext    },
00149 #ifdef _FFR_REPUTATION
00150        { ODKIM_PREFIX "spam",                    dkimf_xs_spam        },
00151 #endif /* _FFR_REPUTATION */
00152        { NULL,                                   NULL                 }
00153 };
00154 # endif /* _FFR_STATSEXT */
00155 
00156 static const luaL_Reg dkimf_lua_lib_final[] =
00157 {
00158        { ODKIM_PREFIX "add_header",              dkimf_xs_addheader   },
00159        { ODKIM_PREFIX "add_rcpt",         dkimf_xs_addrcpt     },
00160        { ODKIM_PREFIX "del_header",              dkimf_xs_delheader   },
00161        { ODKIM_PREFIX "del_rcpt",         dkimf_xs_delrcpt     },
00162        { ODKIM_PREFIX "get_clienthost",   dkimf_xs_clienthost  },
00163        { ODKIM_PREFIX "get_clientip",            dkimf_xs_clientip    },
00164        { ODKIM_PREFIX "get_envfrom",             dkimf_xs_getenvfrom  },
00165        { ODKIM_PREFIX "get_fromdomain",   dkimf_xs_fromdomain  },
00166        { ODKIM_PREFIX "get_header",              dkimf_xs_getheader   },
00167        { ODKIM_PREFIX "get_mtasymbol",           dkimf_xs_getsymval   },
00168        { ODKIM_PREFIX "get_policy",              dkimf_xs_getpolicy   },
00169        { ODKIM_PREFIX "get_rcpt",         dkimf_xs_rcpt        },
00170        { ODKIM_PREFIX "get_rcptarray",           dkimf_xs_rcptarray   },
00171        { ODKIM_PREFIX "get_reputation",   dkimf_xs_getreputation      },
00172        { ODKIM_PREFIX "get_sigarray",            dkimf_xs_getsigarray },
00173        { ODKIM_PREFIX "get_sigcount",            dkimf_xs_getsigcount },
00174        { ODKIM_PREFIX "get_sighandle",           dkimf_xs_getsighandle       },
00175        { ODKIM_PREFIX "log",                     dkimf_xs_log         },
00176        { ODKIM_PREFIX "quarantine",              dkimf_xs_quarantine  },
00177        { ODKIM_PREFIX "parse_field",             dkimf_xs_parsefield  },
00178 # ifdef _FFR_RBL
00179        { ODKIM_PREFIX "rbl_check",        dkimf_xs_rblcheck    },
00180 # endif /* _FFR_RBL */
00181        { ODKIM_PREFIX "rcpt_count",              dkimf_xs_rcptcount   },
00182        { ODKIM_PREFIX "set_reply",        dkimf_xs_setreply    },
00183        { ODKIM_PREFIX "set_result",              dkimf_xs_setresult   },
00184        { ODKIM_PREFIX "sig_bhresult",            dkimf_xs_sigbhresult },
00185        { ODKIM_PREFIX "sig_bodylength",   dkimf_xs_bodylength  },
00186        { ODKIM_PREFIX "sig_canonlength",  dkimf_xs_canonlength },
00187        { ODKIM_PREFIX "sig_getdomain",           dkimf_xs_getsigdomain       },
00188        { ODKIM_PREFIX "sig_getidentity",  dkimf_xs_getsigidentity     },
00189        { ODKIM_PREFIX "sig_result",              dkimf_xs_sigresult   },
00190 # ifdef _FFR_REPUTATION
00191        { ODKIM_PREFIX "spam",                    dkimf_xs_spam        },
00192 # endif /* _FFR_REPUTATION */
00193        { ODKIM_PREFIX "xtag",                    dkimf_xs_xtag        },
00194        { NULL,                                   NULL                 }
00195 };
00196 #endif /* DKIMF_LUA_CONTEXT_HOOKS */
00197 
00198 /*
00199 **  DKIMF_LUA_READER -- "read" a script and make it available to Lua
00200 **
00201 **  Parameters:
00202 **     l -- Lua state
00203 **     data -- pointer to a Lua I/O structure
00204 **     size -- size (returned)
00205 **
00206 **  Return value:
00207 **     Pointer to the data.
00208 */
00209 
00210 static const char *
00211 dkimf_lua_reader(lua_State *l, void *data, size_t *size)
00212 {
00213        struct dkimf_lua_io *io;
00214 
00215        assert(l != NULL);
00216        assert(data != NULL);
00217        assert(size != NULL);
00218 
00219        io = (struct dkimf_lua_io *) data;
00220 
00221        if (io->lua_io_done)
00222        {
00223               *size = 0;
00224               return NULL;
00225        }
00226        else
00227        {
00228               io->lua_io_done = TRUE;
00229               *size = io->lua_io_len;
00230               return io->lua_io_script;
00231        }
00232 }
00233 
00234 /*
00235 **  DKIMF_LUA_WRITER -- extract a compiled script from a Lua state
00236 **
00237 **  Parameters:
00238 **     l -- Lua state
00239 **     buf -- buffer being written
00240 **     sz -- size of buffer 
00241 **     data -- pointer to a Lua I/O structure
00242 **
00243 **  Return value:
00244 **     0 on success, !0 on error.
00245 */
00246 
00247 static int
00248 dkimf_lua_writer(lua_State *l, const void *buf, size_t sz, void *data)
00249 {
00250        struct dkimf_lua_io *io;
00251 
00252        assert(l != NULL);
00253        assert(buf != NULL);
00254        assert(data != NULL);
00255 
00256        io = (struct dkimf_lua_io *) data;
00257 
00258        if (io->lua_io_alloc < io->lua_io_len + sz)
00259        {
00260               size_t newsz;
00261               size_t need;
00262               void *new;
00263 
00264               newsz = io->lua_io_alloc;
00265               need = io->lua_io_len + sz;
00266               while (newsz < need)
00267                      newsz += BUFRSZ;
00268 
00269               if (io->lua_io_alloc == 0)
00270                      new = malloc(newsz);
00271               else
00272                      new = realloc((void *) io->lua_io_script, newsz);
00273 
00274               if (new == NULL)
00275                      return -1;
00276 
00277               io->lua_io_script = new;
00278               io->lua_io_alloc = newsz;
00279        }
00280 
00281        memcpy((void *) (io->lua_io_script + io->lua_io_len), buf, sz);
00282        io->lua_io_len += sz;
00283 
00284        return 0;
00285 }
00286 
00287 /*
00288 **  DKIMF_LUA_ALLOC -- allocate memory
00289 **
00290 **  Parameters:
00291 **     ud -- context (not used)
00292 **     ptr -- pointer (for realloc())
00293 **     osize -- old size
00294 **     nsize --  new size
00295 **
00296 **  Return value:
00297 **     Allocated memory, or NULL on failure.
00298 */
00299 
00300 static void *
00301 dkimf_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
00302 {
00303        if (nsize == 0 && osize != 0)
00304        {
00305               free(ptr);
00306               return NULL;
00307        }
00308 # if LUA_VERSION_NUM == 502
00309        else if (nsize != 0 && ptr == NULL)
00310 # else /* LUA_VERSION_NUM == 502 */
00311        else if (nsize != 0 && osize == 0)
00312 # endif /* LUA_VERSION_NUM == 502 */
00313        {
00314               return malloc(nsize);
00315        }
00316        else
00317        {
00318               return realloc(ptr, nsize);
00319        }
00320 }
00321 
00322 /*
00323 **  DKIMF_LUA_GC_ADD -- add an item for garbage collection
00324 **
00325 **  Parameters:
00326 **     gc -- garbage collection handle
00327 **     item -- item to add
00328 **     type -- item type
00329 **
00330 **  Return value:
00331 **     None.
00332 */
00333 
00334 void
00335 dkimf_lua_gc_add(struct dkimf_lua_gc *gc, void *item, int type)
00336 {
00337        struct dkimf_lua_gc_item *new;
00338 
00339        assert(gc != NULL);
00340        assert(item != NULL);
00341 
00342        new = (struct dkimf_lua_gc_item *) malloc(sizeof *new);
00343        assert(new != NULL);
00344 
00345        new->gci_item = item;
00346        new->gci_type = type;
00347        new->gci_next = NULL;
00348 
00349        if (gc->gc_head == NULL)
00350               gc->gc_head = new;
00351        if (gc->gc_tail != NULL)
00352               gc->gc_tail->gci_next = new;
00353        gc->gc_tail = new;
00354 }
00355 
00356 /*
00357 **  DKIMF_LUA_GC_REMOVE -- remove an item from garbage collection
00358 **
00359 **  Parameters:
00360 **     gc -- garbage collection handle
00361 **     item -- item to remove
00362 **
00363 **  Return value:
00364 **     None.
00365 */
00366 
00367 void
00368 dkimf_lua_gc_remove(struct dkimf_lua_gc *gc, void *item)
00369 {
00370        struct dkimf_lua_gc_item *cur;
00371        struct dkimf_lua_gc_item *prev = NULL;
00372 
00373        assert(gc != NULL);
00374        assert(item != NULL);
00375 
00376        cur = gc->gc_head;
00377 
00378        while (cur != NULL)
00379        {
00380               if (cur->gci_item == item)
00381               {
00382                      if (cur == gc->gc_head)                   /* head */
00383                      {
00384                             gc->gc_head = cur->gci_next;
00385                             free(cur);
00386                             cur = gc->gc_head;
00387                      }
00388                      else if (cur == gc->gc_tail)              /* tail */
00389                      {
00390                             prev->gci_next = NULL;
00391                             gc->gc_tail = prev;
00392                             free(cur);
00393                             cur = NULL;
00394                      }
00395                      else                               /* middle */
00396                      {
00397                             prev->gci_next = cur->gci_next;
00398                             free(cur);
00399                             cur = prev->gci_next;
00400                      }
00401               }
00402               else
00403               {
00404                      prev = cur;
00405                      cur = cur->gci_next;
00406               }
00407        }
00408 }
00409 
00410 /*
00411 **  DKIMF_LUA_GC_CLEANUP -- perform garbage collection
00412 **
00413 **  Parameters:
00414 **     gc -- garbage collection handle
00415 **
00416 **  Return value:
00417 **     None.
00418 */
00419 
00420 void
00421 dkimf_lua_gc_cleanup(struct dkimf_lua_gc *gc)
00422 {
00423        struct dkimf_lua_gc_item *cur;
00424        struct dkimf_lua_gc_item *next;
00425 
00426        assert(gc != NULL);
00427 
00428        cur = gc->gc_head;
00429 
00430        while (cur != NULL)
00431        {
00432               switch (cur->gci_type)
00433               {
00434                 case DKIMF_LUA_GC_DB:
00435                      (void) dkimf_db_close((DKIMF_DB) cur->gci_item);
00436                      break;
00437 
00438                 default:
00439                      assert(0);
00440               }
00441 
00442               next = cur->gci_next;
00443               free(cur);
00444               cur = next;
00445        }
00446 }
00447 
00448 #ifdef DKIMF_LUA_CONTEXT_HOOKS
00449 /*
00450 **  DKIMF_LUA_SETUP_HOOK -- hook to Lua for handling a message during setup
00451 **
00452 **  Parameters:
00453 **     ctx -- session context, for making calls back to opendkim.c
00454 **     script -- script to run
00455 **     scriptlen -- length of script; if 0, use strlen()
00456 **     name -- name of the script (for logging)
00457 **     lres -- Lua result structure
00458 **     keep -- where to save the script (or NULL)
00459 **     funclen -- size of the saved object
00460 **
00461 **  Return value:
00462 **     2 -- processing error
00463 **     1 -- script contains a syntax error
00464 **     0 -- success
00465 **     -1 -- memory allocation failure
00466 **
00467 **  Side effects:
00468 **     lres may be modified to relay the script's signing requests, i.e.
00469 **     which key/selector(s) to use, whether to use "l=", etc.
00470 ** 
00471 **  Notes:
00472 **     Called by mlfi_eoh() so it can decide what signature(s) to apply.
00473 */
00474 
00475 int
00476 dkimf_lua_setup_hook(void *ctx, const char *script, size_t scriptlen,
00477                      const char *name, struct dkimf_lua_script_result *lres,
00478                      void **keep, size_t *funclen)
00479 {
00480        int status;
00481        lua_State *l = NULL;
00482        struct dkimf_lua_io io;
00483        struct dkimf_lua_gc gc;
00484 
00485        assert(script != NULL);
00486        assert(lres != NULL);
00487 
00488        io.lua_io_done = FALSE;
00489        io.lua_io_script = script;
00490        if (scriptlen == 0)
00491               io.lua_io_len = strlen(script);
00492        else
00493               io.lua_io_len = scriptlen;
00494 
00495        gc.gc_head = NULL;
00496        gc.gc_tail = NULL;
00497 
00498        l = lua_newstate(dkimf_lua_alloc, NULL);
00499        if (l == NULL)
00500               return -1;
00501 
00502        luaL_openlibs(l);
00503 
00504        /*
00505        **  Register functions.
00506        */
00507 
00508 # if LUA_VERSION_NUM == 502
00509        luaL_setfunc(l, dkimf_lua_lib_setup, 0);
00510 # else /* LUA_VERSION_NUM == 502 */
00511        luaL_register(l, "odkim", dkimf_lua_lib_setup);
00512 # endif /* LUA_VERSION_NUM == 502 */
00513        lua_pop(l, 1);
00514 
00515        /*
00516        **  Register constants.
00517        */
00518 
00519        /* garbage collection handle */
00520        lua_pushlightuserdata(l, &gc);
00521        lua_setglobal(l, DKIMF_GC);
00522 
00523        /* DB handle constants */
00524        lua_pushnumber(l, DB_DOMAINS);
00525        lua_setglobal(l, "DB_DOMAINS");
00526        lua_pushnumber(l, DB_THIRDPARTY);
00527        lua_setglobal(l, "DB_THIRDPARTY");
00528        lua_pushnumber(l, DB_DONTSIGNTO);
00529        lua_setglobal(l, "DB_DONTSIGNTO");
00530        lua_pushnumber(l, DB_MTAS);
00531        lua_setglobal(l, "DB_MTAS");
00532        lua_pushnumber(l, DB_MACROS);
00533        lua_setglobal(l, "DB_MACROS");
00534 
00535        /* set result code */
00536        lua_pushnumber(l, SMFIS_TEMPFAIL);
00537        lua_setglobal(l, "SMFIS_TEMPFAIL");
00538        lua_pushnumber(l, SMFIS_ACCEPT);
00539        lua_setglobal(l, "SMFIS_ACCEPT");
00540        lua_pushnumber(l, SMFIS_DISCARD);
00541        lua_setglobal(l, "SMFIS_DISCARD");
00542        lua_pushnumber(l, SMFIS_REJECT);
00543        lua_setglobal(l, "SMFIS_REJECT");
00544 
00545        /* filter context */
00546        lua_pushlightuserdata(l, ctx);
00547        lua_setglobal(l, "ctx");
00548 
00549 # ifdef _FFR_LUA_GLOBALS
00550        /* import other globals */
00551        dkimf_import_globals(ctx, l);
00552 # endif /* _FFR_LUA_GLOBALS */
00553 
00554 # if LUA_VERSION_NUM == 502
00555        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name, NULL))
00556 # else /* LUA_VERSION_NUM == 502 */
00557        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name))
00558 # endif /* LUA_VERSION_NUM == 502 */
00559        {
00560          case 0:
00561               break;
00562 
00563          case LUA_ERRSYNTAX:
00564               if (lua_isstring(l, 1))
00565                      lres->lrs_error = strdup(lua_tostring(l, 1));
00566               lua_close(l);
00567               return 1;
00568 
00569          case LUA_ERRMEM:
00570               if (lua_isstring(l, 1))
00571                      lres->lrs_error = strdup(lua_tostring(l, 1));
00572               lua_close(l);
00573               return -1;
00574 
00575          default:
00576               assert(0);
00577        }
00578 
00579        if (keep != NULL && funclen != NULL)
00580        {
00581               io.lua_io_done = FALSE;
00582               io.lua_io_script = NULL;
00583               io.lua_io_len = 0;
00584               io.lua_io_alloc = 0;
00585 
00586               if (lua_dump(l, dkimf_lua_writer, &io) == 0)
00587               {
00588                      *keep = (void *) io.lua_io_script;
00589                      *funclen = io.lua_io_len;
00590               }
00591        }
00592 
00593        status = lua_pcall(l, 0, LUA_MULTRET, 0);
00594        if (lua_isstring(l, 1))
00595               lres->lrs_error = strdup(lua_tostring(l, 1));
00596 
00597        dkimf_lua_gc_cleanup(&gc);
00598 
00599        lua_close(l);
00600 
00601        return (status == 0 ? 0 : 2);
00602 }
00603 
00604 /*
00605 **  DKIMF_LUA_SCREEN_HOOK -- hook to Lua for handling a message after the
00606 **                           verifying handle is established and all headers
00607 **                           have been fed to it
00608 **
00609 **  Parameters:
00610 **     ctx -- session context, for making calls back to opendkim.c
00611 **     script -- script to run
00612 **     scriptlen -- length of script; if 0, use strlen()
00613 **     name -- name of the script (for logging)
00614 **     lres -- Lua result structure
00615 **     keep -- where to save the script (or NULL)
00616 **     funclen -- size of the saved object
00617 **
00618 **  Return value:
00619 **     2 -- processing error
00620 **     1 -- script contains a syntax error
00621 **     0 -- success
00622 **     -1 -- memory allocation failure
00623 **
00624 **  Notes:
00625 **     Called by mlfi_eom() so it can decide whether or not the message
00626 **     is acceptable.
00627 */
00628 
00629 int
00630 dkimf_lua_screen_hook(void *ctx, const char *script, size_t scriptlen,
00631                       const char *name, struct dkimf_lua_script_result *lres,
00632                       void **keep, size_t *funclen)
00633 {
00634        int status;
00635        lua_State *l = NULL;
00636        struct dkimf_lua_io io;
00637        struct dkimf_lua_gc gc;
00638 
00639        assert(script != NULL);
00640        assert(lres != NULL);
00641 
00642        io.lua_io_done = FALSE;
00643        io.lua_io_script = script;
00644        if (scriptlen == 0)
00645               io.lua_io_len = strlen(script);
00646        else
00647               io.lua_io_len = scriptlen;
00648 
00649        gc.gc_head = NULL;
00650        gc.gc_tail = NULL;
00651 
00652        l = lua_newstate(dkimf_lua_alloc, NULL);
00653        if (l == NULL)
00654               return -1;
00655 
00656        luaL_openlibs(l);
00657 
00658        /*
00659        **  Register functions.
00660        */
00661 
00662 # if LUA_VERSION_NUM == 502
00663        luaL_setfuncs(l, dkimf_lua_lib_screen, 0);
00664 # else /* LUA_VERSION_NUM == 502 */
00665        luaL_register(l, "odkim", dkimf_lua_lib_screen);
00666 # endif /* LUA_VERSION_NUM == 502 */
00667        lua_pop(l, 1);
00668 
00669        /*
00670        **  Register constants.
00671        */
00672 
00673        /* garbage collection handle */
00674        lua_pushlightuserdata(l, &gc);
00675        lua_setglobal(l, DKIMF_GC);
00676 
00677        /* DB handles */
00678        lua_pushnumber(l, DB_DOMAINS);
00679        lua_setglobal(l, "DB_DOMAINS");
00680        lua_pushnumber(l, DB_THIRDPARTY);
00681        lua_setglobal(l, "DB_THIRDPARTY");
00682        lua_pushnumber(l, DB_DONTSIGNTO);
00683        lua_setglobal(l, "DB_DONTSIGNTO");
00684        lua_pushnumber(l, DB_MTAS);
00685        lua_setglobal(l, "DB_MTAS");
00686        lua_pushnumber(l, DB_MACROS);
00687        lua_setglobal(l, "DB_MACROS");
00688 
00689        /* milter context */
00690        lua_pushlightuserdata(l, ctx);
00691        lua_setglobal(l, "ctx");
00692 
00693 # ifdef _FFR_LUA_GLOBALS
00694        /* import other globals */
00695        dkimf_import_globals(ctx, l);
00696 # endif /* _FFR_LUA_GLOBALS */
00697 
00698 # if LUA_VERSION_NUM == 502
00699        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name, NULL))
00700 # else /* LUA_VERSION_NUM == 502 */
00701        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name))
00702 # endif /* LUA_VERSION_NUM == 502 */
00703        {
00704          case 0:
00705               break;
00706 
00707          case LUA_ERRSYNTAX:
00708               if (lua_isstring(l, 1))
00709                      lres->lrs_error = strdup(lua_tostring(l, 1));
00710               lua_close(l);
00711               return 1;
00712 
00713          case LUA_ERRMEM:
00714               if (lua_isstring(l, 1))
00715                      lres->lrs_error = strdup(lua_tostring(l, 1));
00716               lua_close(l);
00717               return -1;
00718 
00719          default:
00720               assert(0);
00721        }
00722 
00723        if (keep != NULL && funclen != NULL)
00724        {
00725               io.lua_io_done = FALSE;
00726               io.lua_io_script = NULL;
00727               io.lua_io_len = 0;
00728               io.lua_io_alloc = 0;
00729 
00730               if (lua_dump(l, dkimf_lua_writer, &io) == 0)
00731               {
00732                      *keep = (void *) io.lua_io_script;
00733                      *funclen = io.lua_io_len;
00734               }
00735        }
00736 
00737        status = lua_pcall(l, 0, LUA_MULTRET, 0);
00738        if (lua_isstring(l, 1))
00739               lres->lrs_error = strdup(lua_tostring(l, 1));
00740 
00741        dkimf_lua_gc_cleanup(&gc);
00742 
00743        lua_close(l);
00744 
00745        return (status == 0 ? 0 : 2);
00746 }
00747 
00748 # ifdef _FFR_STATSEXT
00749 /*
00750 **  DKIMF_LUA_STATS_HOOK -- hook to Lua for recording statistics after
00751 **                          verifying has been done
00752 **
00753 **  Parameters:
00754 **     ctx -- session context, for making calls back to opendkim.c
00755 **     script -- script to run
00756 **     scriptlen -- length of script; if 0, use strlen()
00757 **     name -- name of the script (for logging)
00758 **     lres -- Lua result structure
00759 **     keep -- where to save the script (or NULL)
00760 **     funclen -- size of the saved object
00761 **
00762 **  Return value:
00763 **     2 -- processing error
00764 **     1 -- script contains a syntax error
00765 **     0 -- success
00766 **     -1 -- memory allocation failure
00767 **
00768 **  Notes:
00769 **     Called by mlfi_eom() so it can pass extra statistical parameters
00770 **     to the stats recording module.
00771 */
00772 
00773 int
00774 dkimf_lua_stats_hook(void *ctx, const char *script, size_t scriptlen,
00775                      const char *name, struct dkimf_lua_script_result *lres,
00776                      void **keep, size_t *funclen)
00777 {
00778        int status;
00779        lua_State *l = NULL;
00780        struct dkimf_lua_io io;
00781        struct dkimf_lua_gc gc;
00782 
00783        assert(script != NULL);
00784        assert(lres != NULL);
00785 
00786        io.lua_io_done = FALSE;
00787        io.lua_io_script = script;
00788        if (scriptlen == 0)
00789               io.lua_io_len = strlen(script);
00790        else
00791               io.lua_io_len = scriptlen;
00792 
00793        gc.gc_head = NULL;
00794        gc.gc_tail = NULL;
00795 
00796        l = lua_newstate(dkimf_lua_alloc, NULL);
00797        if (l == NULL)
00798               return -1;
00799 
00800        luaL_openlibs(l);
00801 
00802        /*
00803        **  Register functions.
00804        */
00805 
00806 # if LUA_VERSION_NUM == 502
00807        luaL_setfuncs(l, dkimf_lua_lib_stats, 0);
00808 # else /* LUA_VERSION_NUM == 502 */
00809        luaL_register(l, "odkim", dkimf_lua_lib_stats);
00810 # endif /* LUA_VERSION_NUM == 502 */
00811        lua_pop(l, 1);
00812 
00813        /*
00814        **  Register constants.
00815        */
00816 
00817        /* garbage collection handle */
00818        lua_pushlightuserdata(l, &gc);
00819        lua_setglobal(l, DKIMF_GC);
00820 
00821        /* policy codes */
00822        lua_pushnumber(l, DKIMF_POLICY_UNKNOWN);
00823        lua_setglobal(l, "DKIMF_POLICY_UNKNOWN");
00824        lua_pushnumber(l, DKIMF_POLICY_ALL);
00825        lua_setglobal(l, "DKIMF_POLICY_ALL");
00826        lua_pushnumber(l, DKIMF_POLICY_DISCARDABLE);
00827        lua_setglobal(l, "DKIMF_POLICY_DISCARDABLE");
00828        lua_pushnumber(l, DKIMF_POLICY_NONE);
00829        lua_setglobal(l, "DKIMF_POLICY_NONE");
00830        lua_pushnumber(l, DKIMF_POLICY_NXDOMAIN);
00831        lua_setglobal(l, "DKIMF_POLICY_NXDOMAIN");
00832 
00833        /* milter result codes */
00834        lua_pushnumber(l, SMFIS_TEMPFAIL);
00835        lua_setglobal(l, "SMFIS_TEMPFAIL");
00836        lua_pushnumber(l, SMFIS_ACCEPT);
00837        lua_setglobal(l, "SMFIS_ACCEPT");
00838        lua_pushnumber(l, SMFIS_DISCARD);
00839        lua_setglobal(l, "SMFIS_DISCARD");
00840        lua_pushnumber(l, SMFIS_REJECT);
00841        lua_setglobal(l, "SMFIS_REJECT");
00842 
00843        /* signature "bh" result codes */
00844        lua_pushnumber(l, DKIM_SIGBH_UNTESTED);
00845        lua_setglobal(l, "DKIM_SIGBH_UNTESTED");
00846        lua_pushnumber(l, DKIM_SIGBH_MATCH);
00847        lua_setglobal(l, "DKIM_SIGBH_MATCH");
00848        lua_pushnumber(l, DKIM_SIGBH_MISMATCH);
00849        lua_setglobal(l, "DKIM_SIGBH_MISMATCH");
00850 
00851        /* signature error codes */
00852        lua_pushnumber(l, DKIM_SIGERROR_UNKNOWN);
00853        lua_setglobal(l, "DKIM_SIGERROR_UNKNOWN");
00854        lua_pushnumber(l, DKIM_SIGERROR_OK);
00855        lua_setglobal(l, "DKIM_SIGERROR_OK");
00856        lua_pushnumber(l, DKIM_SIGERROR_VERSION);
00857        lua_setglobal(l, "DKIM_SIGERROR_VERSION");
00858        lua_pushnumber(l, DKIM_SIGERROR_DOMAIN);
00859        lua_setglobal(l, "DKIM_SIGERROR_DOMAIN");
00860        lua_pushnumber(l, DKIM_SIGERROR_EXPIRED);
00861        lua_setglobal(l, "DKIM_SIGERROR_EXPIRED");
00862        lua_pushnumber(l, DKIM_SIGERROR_FUTURE);
00863        lua_setglobal(l, "DKIM_SIGERROR_FUTURE");
00864        lua_pushnumber(l, DKIM_SIGERROR_TIMESTAMPS);
00865        lua_setglobal(l, "DKIM_SIGERROR_TIMESTAMPS");
00866        lua_pushnumber(l, DKIM_SIGERROR_INVALID_HC);
00867        lua_setglobal(l, "DKIM_SIGERROR_INVALID_HC");
00868        lua_pushnumber(l, DKIM_SIGERROR_INVALID_BC);
00869        lua_setglobal(l, "DKIM_SIGERROR_INVALID_BC");
00870        lua_pushnumber(l, DKIM_SIGERROR_MISSING_A);
00871        lua_setglobal(l, "DKIM_SIGERROR_MISSING_A");
00872        lua_pushnumber(l, DKIM_SIGERROR_INVALID_A);
00873        lua_setglobal(l, "DKIM_SIGERROR_INVALID_A");
00874        lua_pushnumber(l, DKIM_SIGERROR_MISSING_H);
00875        lua_setglobal(l, "DKIM_SIGERROR_MISSING_H");
00876        lua_pushnumber(l, DKIM_SIGERROR_INVALID_L);
00877        lua_setglobal(l, "DKIM_SIGERROR_INVALID_L");
00878        lua_pushnumber(l, DKIM_SIGERROR_INVALID_Q);
00879        lua_setglobal(l, "DKIM_SIGERROR_INVALID_Q");
00880        lua_pushnumber(l, DKIM_SIGERROR_INVALID_QO);
00881        lua_setglobal(l, "DKIM_SIGERROR_INVALID_QO");
00882        lua_pushnumber(l, DKIM_SIGERROR_MISSING_D);
00883        lua_setglobal(l, "DKIM_SIGERROR_MISSING_D");
00884        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_D);
00885        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_D");
00886        lua_pushnumber(l, DKIM_SIGERROR_MISSING_S);
00887        lua_setglobal(l, "DKIM_SIGERROR_MISSING_S");
00888        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_S);
00889        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_S");
00890        lua_pushnumber(l, DKIM_SIGERROR_MISSING_B);
00891        lua_setglobal(l, "DKIM_SIGERROR_MISSING_B");
00892        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_B);
00893        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_B");
00894        lua_pushnumber(l, DKIM_SIGERROR_CORRUPT_B);
00895        lua_setglobal(l, "DKIM_SIGERROR_CORRUPT_B");
00896        lua_pushnumber(l, DKIM_SIGERROR_NOKEY);
00897        lua_setglobal(l, "DKIM_SIGERROR_NOKEY");
00898        lua_pushnumber(l, DKIM_SIGERROR_DNSSYNTAX);
00899        lua_setglobal(l, "DKIM_SIGERROR_DNSSYNTAX");
00900        lua_pushnumber(l, DKIM_SIGERROR_KEYFAIL);
00901        lua_setglobal(l, "DKIM_SIGERROR_KEYFAIL");
00902        lua_pushnumber(l, DKIM_SIGERROR_MISSING_BH);
00903        lua_setglobal(l, "DKIM_SIGERROR_MISSING_BH");
00904        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_BH);
00905        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_BH");
00906        lua_pushnumber(l, DKIM_SIGERROR_CORRUPT_BH);
00907        lua_setglobal(l, "DKIM_SIGERROR_CORRUPT_BH");
00908        lua_pushnumber(l, DKIM_SIGERROR_BADSIG);
00909        lua_setglobal(l, "DKIM_SIGERROR_BADSIG");
00910        lua_pushnumber(l, DKIM_SIGERROR_SUBDOMAIN);
00911        lua_setglobal(l, "DKIM_SIGERROR_SUBDOMAIN");
00912        lua_pushnumber(l, DKIM_SIGERROR_MULTIREPLY);
00913        lua_setglobal(l, "DKIM_SIGERROR_MULTIREPLY");
00914        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_H);
00915        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_H");
00916        lua_pushnumber(l, DKIM_SIGERROR_INVALID_H);
00917        lua_setglobal(l, "DKIM_SIGERROR_INVALID_H");
00918        lua_pushnumber(l, DKIM_SIGERROR_TOOLARGE_L);
00919        lua_setglobal(l, "DKIM_SIGERROR_TOOLARGE_L");
00920        lua_pushnumber(l, DKIM_SIGERROR_MBSFAILED);
00921        lua_setglobal(l, "DKIM_SIGERROR_MBSFAILED");
00922        lua_pushnumber(l, DKIM_SIGERROR_KEYVERSION);
00923        lua_setglobal(l, "DKIM_SIGERROR_KEYVERSION");
00924        lua_pushnumber(l, DKIM_SIGERROR_KEYUNKNOWNHASH);
00925        lua_setglobal(l, "DKIM_SIGERROR_KEYUNKNOWNHASH");
00926        lua_pushnumber(l, DKIM_SIGERROR_KEYHASHMISMATCH);
00927        lua_setglobal(l, "DKIM_SIGERROR_KEYHASHMISMATCH");
00928        lua_pushnumber(l, DKIM_SIGERROR_NOTEMAILKEY);
00929        lua_setglobal(l, "DKIM_SIGERROR_NOTEMAILKEY");
00930        lua_pushnumber(l, DKIM_SIGERROR_KEYTYPEMISSING);
00931        lua_setglobal(l, "DKIM_SIGERROR_KEYTYPEMISSING");
00932        lua_pushnumber(l, DKIM_SIGERROR_KEYTYPEUNKNOWN);
00933        lua_setglobal(l, "DKIM_SIGERROR_KEYTYPEUNKNOWN");
00934        lua_pushnumber(l, DKIM_SIGERROR_KEYREVOKED);
00935        lua_setglobal(l, "DKIM_SIGERROR_KEYREVOKED");
00936        lua_pushnumber(l, DKIM_SIGERROR_KEYDECODE);
00937        lua_setglobal(l, "DKIM_SIGERROR_KEYDECODE");
00938 
00939        /* milter context */
00940        lua_pushlightuserdata(l, ctx);
00941        lua_setglobal(l, "ctx");
00942 
00943 # ifdef _FFR_LUA_GLOBALS
00944        /* import other globals */
00945        dkimf_import_globals(ctx, l);
00946 # endif /* _FFR_LUA_GLOBALS */
00947 
00948 # if LUA_VERSION_NUM == 502
00949        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name, NULL))
00950 # else /* LUA_VERSION_NUM == 502 */
00951        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name))
00952 # endif /* LUA_VERSION_NUM == 502 */
00953        {
00954          case 0:
00955               break;
00956 
00957          case LUA_ERRSYNTAX:
00958               if (lua_isstring(l, 1))
00959                      lres->lrs_error = strdup(lua_tostring(l, 1));
00960               lua_close(l);
00961               return 1;
00962 
00963          case LUA_ERRMEM:
00964               if (lua_isstring(l, 1))
00965                      lres->lrs_error = strdup(lua_tostring(l, 1));
00966               lua_close(l);
00967               return -1;
00968 
00969          default:
00970               assert(0);
00971        }
00972 
00973        if (keep != NULL && funclen != NULL)
00974        {
00975               io.lua_io_done = FALSE;
00976               io.lua_io_script = NULL;
00977               io.lua_io_len = 0;
00978               io.lua_io_alloc = 0;
00979 
00980               if (lua_dump(l, dkimf_lua_writer, &io) == 0)
00981               {
00982                      *keep = (void *) io.lua_io_script;
00983                      *funclen = io.lua_io_len;
00984               }
00985        }
00986 
00987        status = lua_pcall(l, 0, LUA_MULTRET, 0);
00988        if (lua_isstring(l, 1))
00989               lres->lrs_error = strdup(lua_tostring(l, 1));
00990 
00991        dkimf_lua_gc_cleanup(&gc);
00992 
00993        lua_close(l);
00994 
00995        return (status == 0 ? 0 : 2);
00996 }
00997 # endif /* _FFR_STATSEXT */
00998 
00999 /*
01000 **  DKIMF_LUA_FINAL_HOOK -- hook to Lua for handling a message after all
01001 **                          signing and verifying has been done
01002 **
01003 **  Parameters:
01004 **     ctx -- session context, for making calls back to opendkim.c
01005 **     script -- script to run
01006 **     scriptlen -- length of script; if 0, use strlen()
01007 **     name -- name of the script (for logging)
01008 **     lres -- Lua result structure
01009 **     keep -- where to save the script (or NULL)
01010 **     funclen -- size of the saved object
01011 **
01012 **  Return value:
01013 **     2 -- processing error
01014 **     1 -- script contains a syntax error
01015 **     0 -- success
01016 **     -1 -- memory allocation failure
01017 **
01018 **  Notes:
01019 **     Called by mlfi_eom() so it can decide whether or not the message
01020 **     is acceptable.
01021 */
01022 
01023 int
01024 dkimf_lua_final_hook(void *ctx, const char *script, size_t scriptlen,
01025                      const char *name, struct dkimf_lua_script_result *lres,
01026                      void **keep, size_t *funclen)
01027 {
01028        int status;
01029        lua_State *l = NULL;
01030        struct dkimf_lua_io io;
01031        struct dkimf_lua_gc gc;
01032 
01033        assert(script != NULL);
01034        assert(lres != NULL);
01035 
01036        io.lua_io_done = FALSE;
01037        io.lua_io_script = script;
01038        if (scriptlen == 0)
01039               io.lua_io_len = strlen(script);
01040        else
01041               io.lua_io_len = scriptlen;
01042 
01043        gc.gc_head = NULL;
01044        gc.gc_tail = NULL;
01045 
01046        l = lua_newstate(dkimf_lua_alloc, NULL);
01047        if (l == NULL)
01048               return -1;
01049 
01050        luaL_openlibs(l);
01051 
01052        /*
01053        **  Register functions.
01054        */
01055 
01056 # if LUA_VERSION_NUM == 502
01057        luaL_setfuncs(l, dkimf_lua_lib_final, 0);
01058 # else /* LUA_VERSION_NUM == 502 */
01059        luaL_register(l, "odkim", dkimf_lua_lib_final);
01060 # endif /* LUA_VERSION_NUM == 502 */
01061        lua_pop(l, 1);
01062 
01063        /*
01064        **  Register constants.
01065        */
01066 
01067        /* garbage collection handle */
01068        lua_pushlightuserdata(l, &gc);
01069        lua_setglobal(l, DKIMF_GC);
01070 
01071        /* policy codes */
01072        lua_pushnumber(l, DKIMF_POLICY_UNKNOWN);
01073        lua_setglobal(l, "DKIMF_POLICY_UNKNOWN");
01074        lua_pushnumber(l, DKIMF_POLICY_ALL);
01075        lua_setglobal(l, "DKIMF_POLICY_ALL");
01076        lua_pushnumber(l, DKIMF_POLICY_DISCARDABLE);
01077        lua_setglobal(l, "DKIMF_POLICY_DISCARDABLE");
01078        lua_pushnumber(l, DKIMF_POLICY_NONE);
01079        lua_setglobal(l, "DKIMF_POLICY_NONE");
01080        lua_pushnumber(l, DKIMF_POLICY_NXDOMAIN);
01081        lua_setglobal(l, "DKIMF_POLICY_NXDOMAIN");
01082 
01083        /* milter result codes */
01084        lua_pushnumber(l, SMFIS_TEMPFAIL);
01085        lua_setglobal(l, "SMFIS_TEMPFAIL");
01086        lua_pushnumber(l, SMFIS_ACCEPT);
01087        lua_setglobal(l, "SMFIS_ACCEPT");
01088        lua_pushnumber(l, SMFIS_DISCARD);
01089        lua_setglobal(l, "SMFIS_DISCARD");
01090        lua_pushnumber(l, SMFIS_REJECT);
01091        lua_setglobal(l, "SMFIS_REJECT");
01092 
01093        /* signature "bh" result codes */
01094        lua_pushnumber(l, DKIM_SIGBH_UNTESTED);
01095        lua_setglobal(l, "DKIM_SIGBH_UNTESTED");
01096        lua_pushnumber(l, DKIM_SIGBH_MATCH);
01097        lua_setglobal(l, "DKIM_SIGBH_MATCH");
01098        lua_pushnumber(l, DKIM_SIGBH_MISMATCH);
01099        lua_setglobal(l, "DKIM_SIGBH_MISMATCH");
01100 
01101        /* signature error codes */
01102        lua_pushnumber(l, DKIM_SIGERROR_UNKNOWN);
01103        lua_setglobal(l, "DKIM_SIGERROR_UNKNOWN");
01104        lua_pushnumber(l, DKIM_SIGERROR_OK);
01105        lua_setglobal(l, "DKIM_SIGERROR_OK");
01106        lua_pushnumber(l, DKIM_SIGERROR_VERSION);
01107        lua_setglobal(l, "DKIM_SIGERROR_VERSION");
01108        lua_pushnumber(l, DKIM_SIGERROR_DOMAIN);
01109        lua_setglobal(l, "DKIM_SIGERROR_DOMAIN");
01110        lua_pushnumber(l, DKIM_SIGERROR_EXPIRED);
01111        lua_setglobal(l, "DKIM_SIGERROR_EXPIRED");
01112        lua_pushnumber(l, DKIM_SIGERROR_FUTURE);
01113        lua_setglobal(l, "DKIM_SIGERROR_FUTURE");
01114        lua_pushnumber(l, DKIM_SIGERROR_TIMESTAMPS);
01115        lua_setglobal(l, "DKIM_SIGERROR_TIMESTAMPS");
01116        lua_pushnumber(l, DKIM_SIGERROR_INVALID_HC);
01117        lua_setglobal(l, "DKIM_SIGERROR_INVALID_HC");
01118        lua_pushnumber(l, DKIM_SIGERROR_INVALID_BC);
01119        lua_setglobal(l, "DKIM_SIGERROR_INVALID_BC");
01120        lua_pushnumber(l, DKIM_SIGERROR_MISSING_A);
01121        lua_setglobal(l, "DKIM_SIGERROR_MISSING_A");
01122        lua_pushnumber(l, DKIM_SIGERROR_INVALID_A);
01123        lua_setglobal(l, "DKIM_SIGERROR_INVALID_A");
01124        lua_pushnumber(l, DKIM_SIGERROR_MISSING_H);
01125        lua_setglobal(l, "DKIM_SIGERROR_MISSING_H");
01126        lua_pushnumber(l, DKIM_SIGERROR_INVALID_L);
01127        lua_setglobal(l, "DKIM_SIGERROR_INVALID_L");
01128        lua_pushnumber(l, DKIM_SIGERROR_INVALID_Q);
01129        lua_setglobal(l, "DKIM_SIGERROR_INVALID_Q");
01130        lua_pushnumber(l, DKIM_SIGERROR_INVALID_QO);
01131        lua_setglobal(l, "DKIM_SIGERROR_INVALID_QO");
01132        lua_pushnumber(l, DKIM_SIGERROR_MISSING_D);
01133        lua_setglobal(l, "DKIM_SIGERROR_MISSING_D");
01134        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_D);
01135        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_D");
01136        lua_pushnumber(l, DKIM_SIGERROR_MISSING_S);
01137        lua_setglobal(l, "DKIM_SIGERROR_MISSING_S");
01138        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_S);
01139        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_S");
01140        lua_pushnumber(l, DKIM_SIGERROR_MISSING_B);
01141        lua_setglobal(l, "DKIM_SIGERROR_MISSING_B");
01142        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_B);
01143        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_B");
01144        lua_pushnumber(l, DKIM_SIGERROR_CORRUPT_B);
01145        lua_setglobal(l, "DKIM_SIGERROR_CORRUPT_B");
01146        lua_pushnumber(l, DKIM_SIGERROR_NOKEY);
01147        lua_setglobal(l, "DKIM_SIGERROR_NOKEY");
01148        lua_pushnumber(l, DKIM_SIGERROR_DNSSYNTAX);
01149        lua_setglobal(l, "DKIM_SIGERROR_DNSSYNTAX");
01150        lua_pushnumber(l, DKIM_SIGERROR_KEYFAIL);
01151        lua_setglobal(l, "DKIM_SIGERROR_KEYFAIL");
01152        lua_pushnumber(l, DKIM_SIGERROR_MISSING_BH);
01153        lua_setglobal(l, "DKIM_SIGERROR_MISSING_BH");
01154        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_BH);
01155        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_BH");
01156        lua_pushnumber(l, DKIM_SIGERROR_CORRUPT_BH);
01157        lua_setglobal(l, "DKIM_SIGERROR_CORRUPT_BH");
01158        lua_pushnumber(l, DKIM_SIGERROR_BADSIG);
01159        lua_setglobal(l, "DKIM_SIGERROR_BADSIG");
01160        lua_pushnumber(l, DKIM_SIGERROR_SUBDOMAIN);
01161        lua_setglobal(l, "DKIM_SIGERROR_SUBDOMAIN");
01162        lua_pushnumber(l, DKIM_SIGERROR_MULTIREPLY);
01163        lua_setglobal(l, "DKIM_SIGERROR_MULTIREPLY");
01164        lua_pushnumber(l, DKIM_SIGERROR_EMPTY_H);
01165        lua_setglobal(l, "DKIM_SIGERROR_EMPTY_H");
01166        lua_pushnumber(l, DKIM_SIGERROR_INVALID_H);
01167        lua_setglobal(l, "DKIM_SIGERROR_INVALID_H");
01168        lua_pushnumber(l, DKIM_SIGERROR_TOOLARGE_L);
01169        lua_setglobal(l, "DKIM_SIGERROR_TOOLARGE_L");
01170        lua_pushnumber(l, DKIM_SIGERROR_MBSFAILED);
01171        lua_setglobal(l, "DKIM_SIGERROR_MBSFAILED");
01172        lua_pushnumber(l, DKIM_SIGERROR_KEYVERSION);
01173        lua_setglobal(l, "DKIM_SIGERROR_KEYVERSION");
01174        lua_pushnumber(l, DKIM_SIGERROR_KEYUNKNOWNHASH);
01175        lua_setglobal(l, "DKIM_SIGERROR_KEYUNKNOWNHASH");
01176        lua_pushnumber(l, DKIM_SIGERROR_KEYHASHMISMATCH);
01177        lua_setglobal(l, "DKIM_SIGERROR_KEYHASHMISMATCH");
01178        lua_pushnumber(l, DKIM_SIGERROR_NOTEMAILKEY);
01179        lua_setglobal(l, "DKIM_SIGERROR_NOTEMAILKEY");
01180        lua_pushnumber(l, DKIM_SIGERROR_KEYTYPEMISSING);
01181        lua_setglobal(l, "DKIM_SIGERROR_KEYTYPEMISSING");
01182        lua_pushnumber(l, DKIM_SIGERROR_KEYTYPEUNKNOWN);
01183        lua_setglobal(l, "DKIM_SIGERROR_KEYTYPEUNKNOWN");
01184        lua_pushnumber(l, DKIM_SIGERROR_KEYREVOKED);
01185        lua_setglobal(l, "DKIM_SIGERROR_KEYREVOKED");
01186        lua_pushnumber(l, DKIM_SIGERROR_KEYDECODE);
01187        lua_setglobal(l, "DKIM_SIGERROR_KEYDECODE");
01188 
01189        /* milter context */
01190        lua_pushlightuserdata(l, ctx);
01191        lua_setglobal(l, "ctx");
01192 
01193 # ifdef _FFR_LUA_GLOBALS
01194        /* import other globals */
01195        dkimf_import_globals(ctx, l);
01196 # endif /* _FFR_LUA_GLOBALS */
01197 
01198 # if LUA_VERSION_NUM == 502
01199        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name, NULL))
01200 # else /* LUA_VERSION_NUM == 502 */
01201        switch (lua_load(l, dkimf_lua_reader, (void *) &io, name))
01202 # endif /* LUA_VERSION_NUM == 502 */
01203        {
01204          case 0:
01205               break;
01206 
01207          case LUA_ERRSYNTAX:
01208               if (lua_isstring(l, 1))
01209                      lres->lrs_error = strdup(lua_tostring(l, 1));
01210               lua_close(l);
01211               return 1;
01212 
01213          case LUA_ERRMEM:
01214               if (lua_isstring(l, 1))
01215                      lres->lrs_error = strdup(lua_tostring(l, 1));
01216               lua_close(l);
01217               return -1;
01218 
01219          default:
01220               assert(0);
01221        }
01222 
01223        if (keep != NULL && funclen != NULL)
01224        {
01225               io.lua_io_done = FALSE;
01226               io.lua_io_script = NULL;
01227               io.lua_io_len = 0;
01228               io.lua_io_alloc = 0;
01229 
01230               if (lua_dump(l, dkimf_lua_writer, &io) == 0)
01231               {
01232                      *keep = (void *) io.lua_io_script;
01233                      *funclen = io.lua_io_len;
01234               }
01235        }
01236 
01237        status = lua_pcall(l, 0, LUA_MULTRET, 0);
01238        if (lua_isstring(l, 1))
01239               lres->lrs_error = strdup(lua_tostring(l, 1));
01240 
01241        dkimf_lua_gc_cleanup(&gc);
01242 
01243        lua_close(l);
01244 
01245        return (status == 0 ? 0 : 2);
01246 }
01247 #endif /* DKIMF_LUA_CONTEXT_HOOKS */
01248 
01249 /*
01250 **  DKIMF_LUA_DB_HOOK -- hook to Lua for handling a DB query
01251 **
01252 **  Parameters:
01253 **     script -- script to run
01254 **     scriptlen -- length of script; if 0, use strlen()
01255 **     query -- query string
01256 **     lres -- Lua result structure
01257 **     keep -- where to save the script (or NULL)
01258 **     funclen -- size of the saved object
01259 **
01260 **  Return value:
01261 **     2 -- processing error
01262 **     1 -- script contains a syntax error
01263 **     0 -- success
01264 **     -1 -- memory allocation failure
01265 */
01266 
01267 int
01268 dkimf_lua_db_hook(const char *script, size_t scriptlen, const char *query,
01269                   struct dkimf_lua_script_result *lres, void **keep,
01270                   size_t *funclen)
01271 {
01272        int status;
01273        struct dkimf_lua_io io;
01274        lua_State *l = NULL;
01275 
01276        assert(script != NULL);
01277        assert(lres != NULL);
01278 
01279        io.lua_io_done = FALSE;
01280        io.lua_io_script = script;
01281        if (scriptlen == 0)
01282               io.lua_io_len = strlen(script);
01283        else
01284               io.lua_io_len = scriptlen;
01285 
01286        l = lua_newstate(dkimf_lua_alloc, NULL);
01287        if (l == NULL)
01288               return -1;
01289 
01290        luaL_openlibs(l);
01291 
01292        /* query string */
01293        if (query == NULL)
01294               lua_pushnil(l);
01295        else
01296               lua_pushstring(l, query);
01297        lua_setglobal(l, "query");
01298 
01299        switch (lua_load(l, dkimf_lua_reader, (void *) &io, script))
01300        {
01301          case 0:
01302               break;
01303 
01304          case LUA_ERRSYNTAX:
01305               if (lua_isstring(l, 1))
01306                      lres->lrs_error = strdup(lua_tostring(l, 1));
01307               lua_close(l);
01308               return 1;
01309 
01310          case LUA_ERRMEM:
01311               if (lua_isstring(l, 1))
01312                      lres->lrs_error = strdup(lua_tostring(l, 1));
01313               lua_close(l);
01314               return -1;
01315 
01316          default:
01317               assert(0);
01318        }
01319 
01320        if (keep != NULL && funclen != NULL)
01321        {
01322               io.lua_io_done = FALSE;
01323               io.lua_io_script = NULL;
01324               io.lua_io_len = 0;
01325               io.lua_io_alloc = 0;
01326 
01327               if (lua_dump(l, dkimf_lua_writer, &io) == 0)
01328               {
01329                      *keep = (void *) io.lua_io_script;
01330                      *funclen = io.lua_io_len;
01331               }
01332        }
01333 
01334        status = lua_pcall(l, 0, LUA_MULTRET, 0);
01335        if (status != 0 && lua_isstring(l, 1))
01336        {
01337               lres->lrs_error = strdup(lua_tostring(l, 1));
01338               lres->lrs_rcount = 0;
01339        }
01340        else if (status == 0)
01341        {
01342               size_t asz;
01343 
01344               lres->lrs_rcount = lua_gettop(l);
01345 
01346               asz = sizeof(char *) * lres->lrs_rcount;
01347               lres->lrs_results = (char **) malloc(asz);
01348               if (lres->lrs_results != NULL)
01349               {
01350                      int c;
01351 
01352                      for (c = 0; c < lres->lrs_rcount; c++)
01353                      {
01354                             lres->lrs_results[c] = strdup(lua_tostring(l,
01355                                                                        c + 1));
01356                      }
01357               }
01358        }
01359 
01360        lua_close(l);
01361 
01362        return (status == 0 ? 0 : 2);
01363 }
01364 #endif /* USE_LUA */