Changeset e02dd8c in mod_gnutls for src/gnutls_lua.c


Ignore:
Timestamp:
Oct 25, 2010, 3:21:04 PM (10 years ago)
Author:
Nikos Mavrogiannopoulos <nmav@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, msva, proxy-ticket, upstream
Children:
b59327c
Parents:
62def2f
Message:

indented code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_lua.c

    r62def2f re02dd8c  
    2626static char *MGS_LUA_RRKEY = "request_rec";
    2727
    28 static request_rec *mgs_lua_getrr(lua_State *lvm)
    29 {
    30     request_rec *r;
    31    
    32     /* Push the request_rec off the registry, onto the stack. */
    33     lua_pushlightuserdata(lvm, MGS_LUA_RRKEY);
    34     lua_gettable(lvm, LUA_REGISTRYINDEX);
    35     r = lua_touserdata(lvm, -1);
    36     lua_pop(lvm, 1);
    37     return r;
    38 }
    39 
    40 static int get_request_table(lua_State *lvm, long offset)
    41 {   
    42     const char *key;
    43     request_rec *r;
    44     const char *value;
    45     apr_table_t *t;
    46     key = luaL_checkstring(lvm, 1);
    47 
    48     r = mgs_lua_getrr(lvm);
    49    
    50     t = *(apr_table_t **)((char *)r + offset);
    51 
    52     value = apr_table_get(t, key);
    53 
    54     if (value) {
    55         lua_pushstring(lvm, value);
    56         return 1;
    57     }
    58     else {
    59         return 0;
    60     }
    61 }
    62 
    63 static int mgs_lua_getenv(lua_State *lvm)
    64 {
    65     return get_request_table(lvm, APR_OFFSETOF(request_rec, subprocess_env));
    66 }
    67 
    68 static int mgs_lua_getheader(lua_State *lvm)
    69 {   
    70     return get_request_table(lvm, APR_OFFSETOF(request_rec, headers_in));
    71 }
     28static request_rec *mgs_lua_getrr(lua_State * lvm)
     29{
     30        request_rec *r;
     31
     32        /* Push the request_rec off the registry, onto the stack. */
     33        lua_pushlightuserdata(lvm, MGS_LUA_RRKEY);
     34        lua_gettable(lvm, LUA_REGISTRYINDEX);
     35        r = lua_touserdata(lvm, -1);
     36        lua_pop(lvm, 1);
     37        return r;
     38}
     39
     40static int get_request_table(lua_State * lvm, long offset)
     41{
     42        const char *key;
     43        request_rec *r;
     44        const char *value;
     45        apr_table_t *t;
     46        key = luaL_checkstring(lvm, 1);
     47
     48        r = mgs_lua_getrr(lvm);
     49
     50        t = *(apr_table_t **) ((char *) r + offset);
     51
     52        value = apr_table_get(t, key);
     53
     54        if (value) {
     55                lua_pushstring(lvm, value);
     56                return 1;
     57        } else {
     58                return 0;
     59        }
     60}
     61
     62static int mgs_lua_getenv(lua_State * lvm)
     63{
     64        return get_request_table(lvm,
     65                                 APR_OFFSETOF(request_rec,
     66                                              subprocess_env));
     67}
     68
     69static int mgs_lua_getheader(lua_State * lvm)
     70{
     71        return get_request_table(lvm,
     72                                 APR_OFFSETOF(request_rec, headers_in));
     73}
    7274
    7375static const luaL_reg mgs_lua_reg[] = {
    74     {"getenv", mgs_lua_getenv},
    75     {"header", mgs_lua_getheader},
    76     {NULL, NULL}
     76        {"getenv", mgs_lua_getenv},
     77        {"header", mgs_lua_getheader},
     78        {NULL, NULL}
    7779};
    7880
    79 lua_State* get_luastate()
    80 {
    81     lua_State* lvm = lua_open();
    82     luaopen_base(lvm);
    83     luaopen_io(lvm);
    84     luaopen_table(lvm);
    85     luaopen_string(lvm);
    86     luaopen_math(lvm);
    87     luaopen_loadlib(lvm);
    88     luaL_openlib(lvm, "ap", mgs_lua_reg, 0);
    89    
    90     return lvm;
    91 }
    92 
    93 int mgs_authz_lua(request_rec* r)
    94 {
    95     int rv;
    96     lua_State* lvm;
    97     mgs_dirconf_rec *dc = ap_get_module_config(r->per_dir_config,
    98                                                &gnutls_module);
    99    
    100     if (dc->lua_bytecode_len <= 0) {
    101         return 0;
    102     }
    103    
    104     lvm = get_luastate();
    105     lua_pushlightuserdata(lvm, MGS_LUA_RRKEY);
    106     lua_pushlightuserdata(lvm, r);
    107     lua_settable(lvm, LUA_REGISTRYINDEX);
    108    
    109     /* Push Bytecode onto the stack */
    110     rv = luaL_loadbuffer(lvm, dc->lua_bytecode, dc->lua_bytecode_len, "gnutls-lua");
    111 
    112     if (rv != 0) {
    113         /* Get the Error message */
    114         const char* error = lua_tostring(lvm, -1);
    115         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    116                       "GnuTLS: Error Loading Lua Bytecode: %s", error);
    117         lua_pop(lvm, 1);
    118         return -1;
    119     }
    120    
    121     rv = lua_pcall(lvm, 0, 1, 0);
    122     if (rv != 0) {
    123         /* Get the Error message */
    124         const char* error = lua_tostring(lvm, -1);
    125         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    126                       "GnuTLS: Error Running Lua: %s", error);
    127         lua_pop(lvm, 1);
    128         return -1;
    129     }
    130    
    131     rv = (int)lua_tonumber(lvm, -1);
    132     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
    133                   "GnuTLS: (%d) Lua Return: %d",
    134                   dc->lua_bytecode_len, rv);
    135     lua_pop(lvm, 1);
    136     lua_close(lvm);
    137     return rv;
    138 }
    139 
    140 static apr_size_t config_getstr(ap_configfile_t *cfg, char *buf, size_t bufsiz)
    141 {
    142     apr_size_t i = 0;
    143    
    144     if (cfg->getstr) {
    145         const char *res = (cfg->getstr)(buf, bufsiz, cfg->param);
    146         if (res) {
    147             i = strlen(buf);
    148             if (i && buf[i - 1] == '\n') ++cfg->line_number;
    149         }
    150         else {
    151             buf[0] = '\0';
    152             i = 0;
    153         }
    154     }
    155     else {
    156         while (i < bufsiz) {
    157             int ch = (cfg->getch)(cfg->param);
    158             if (ch == EOF) break;
    159             buf[i++] = ch;
    160             if (ch == '\n') {
    161                 ++cfg->line_number;
    162                 break;
    163             }
    164         }
    165     }
    166     return i;
     81lua_State *get_luastate()
     82{
     83        lua_State *lvm = lua_open();
     84        luaopen_base(lvm);
     85        luaopen_io(lvm);
     86        luaopen_table(lvm);
     87        luaopen_string(lvm);
     88        luaopen_math(lvm);
     89        luaopen_loadlib(lvm);
     90        luaL_openlib(lvm, "ap", mgs_lua_reg, 0);
     91
     92        return lvm;
     93}
     94
     95int mgs_authz_lua(request_rec * r)
     96{
     97        int rv;
     98        lua_State *lvm;
     99        mgs_dirconf_rec *dc = ap_get_module_config(r->per_dir_config,
     100                                                   &gnutls_module);
     101
     102        if (dc->lua_bytecode_len <= 0) {
     103                return 0;
     104        }
     105
     106        lvm = get_luastate();
     107        lua_pushlightuserdata(lvm, MGS_LUA_RRKEY);
     108        lua_pushlightuserdata(lvm, r);
     109        lua_settable(lvm, LUA_REGISTRYINDEX);
     110
     111        /* Push Bytecode onto the stack */
     112        rv = luaL_loadbuffer(lvm, dc->lua_bytecode, dc->lua_bytecode_len,
     113                             "gnutls-lua");
     114
     115        if (rv != 0) {
     116                /* Get the Error message */
     117                const char *error = lua_tostring(lvm, -1);
     118                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     119                              "GnuTLS: Error Loading Lua Bytecode: %s",
     120                              error);
     121                lua_pop(lvm, 1);
     122                return -1;
     123        }
     124
     125        rv = lua_pcall(lvm, 0, 1, 0);
     126        if (rv != 0) {
     127                /* Get the Error message */
     128                const char *error = lua_tostring(lvm, -1);
     129                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     130                              "GnuTLS: Error Running Lua: %s", error);
     131                lua_pop(lvm, 1);
     132                return -1;
     133        }
     134
     135        rv = (int) lua_tonumber(lvm, -1);
     136        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     137                      "GnuTLS: (%d) Lua Return: %d",
     138                      dc->lua_bytecode_len, rv);
     139        lua_pop(lvm, 1);
     140        lua_close(lvm);
     141        return rv;
     142}
     143
     144static apr_size_t config_getstr(ap_configfile_t * cfg, char *buf,
     145                                size_t bufsiz)
     146{
     147        apr_size_t i = 0;
     148
     149        if (cfg->getstr) {
     150                const char *res = (cfg->getstr) (buf, bufsiz, cfg->param);
     151                if (res) {
     152                        i = strlen(buf);
     153                        if (i && buf[i - 1] == '\n')
     154                                ++cfg->line_number;
     155                } else {
     156                        buf[0] = '\0';
     157                        i = 0;
     158                }
     159        } else {
     160                while (i < bufsiz) {
     161                        int ch = (cfg->getch) (cfg->param);
     162                        if (ch == EOF)
     163                                break;
     164                        buf[i++] = ch;
     165                        if (ch == '\n') {
     166                                ++cfg->line_number;
     167                                break;
     168                        }
     169                }
     170        }
     171        return i;
    167172}
    168173
    169174struct cr_ctx {
    170     ap_configfile_t *cfp;
    171     size_t startline;
    172     char buf[HUGE_STRING_LEN];
     175        ap_configfile_t *cfp;
     176        size_t startline;
     177        char buf[HUGE_STRING_LEN];
    173178};
    174179
    175180static const char *LUACMD = "gnutlsrequire";
    176 static const char *lf = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
     181static const char *lf =
     182    "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
    177183#define N_LF 32
    178184
    179 static const char *direct_chunkreader(lua_State *lvm, void *udata, size_t *plen)
    180 {
    181     const char *p;
    182     struct cr_ctx *ctx = udata;
    183    
    184     if (ctx->startline) {
    185         *plen = ctx->startline > N_LF ? N_LF : ctx->startline;
    186         ctx->startline -= *plen;
    187         return lf;
    188     }
    189     *plen = config_getstr(ctx->cfp, ctx->buf, HUGE_STRING_LEN);
    190    
    191     for (p = ctx->buf; isspace(*p); ++p);
    192     if (p[0] == '<' && p[1] == '/') {
    193         int i = 0;
    194         while (i < strlen(LUACMD)) {
    195             if (tolower(p[i + 2]) != LUACMD[i]) return ctx->buf;
    196             ++i;
    197         }
    198         *plen = 0;
    199         return NULL;
    200     }
    201     return ctx->buf;
    202 }
    203 
    204 static int ldump_writer (lua_State *L, const void* b, size_t size, void* B) {
    205     (void)L;
    206     luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
    207     return 1;
     185static const char *direct_chunkreader(lua_State * lvm, void *udata,
     186                                      size_t * plen)
     187{
     188        const char *p;
     189        struct cr_ctx *ctx = udata;
     190
     191        if (ctx->startline) {
     192                *plen = ctx->startline > N_LF ? N_LF : ctx->startline;
     193                ctx->startline -= *plen;
     194                return lf;
     195        }
     196        *plen = config_getstr(ctx->cfp, ctx->buf, HUGE_STRING_LEN);
     197
     198        for (p = ctx->buf; isspace(*p); ++p);
     199        if (p[0] == '<' && p[1] == '/') {
     200                int i = 0;
     201                while (i < strlen(LUACMD)) {
     202                        if (tolower(p[i + 2]) != LUACMD[i])
     203                                return ctx->buf;
     204                        ++i;
     205                }
     206                *plen = 0;
     207                return NULL;
     208        }
     209        return ctx->buf;
     210}
     211
     212static int ldump_writer(lua_State * L, const void *b, size_t size, void *B)
     213{
     214        (void) L;
     215        luaL_addlstring((luaL_Buffer *) B, (const char *) b, size);
     216        return 1;
    208217}
    209218
    210219/* a bytecode buffer*/
    211220typedef struct bcbuf_ctx {
    212     apr_size_t buflen;
    213     char* buf;
     221        apr_size_t buflen;
     222        char *buf;
    214223} bcbuf_ctx;
    215224
    216 const char *mgs_set_require_section(cmd_parms *cmd, void *mconfig, const char *arg)
    217 {
    218     apr_size_t bytecode_len;
    219     const char* bytecode;
    220     bcbuf_ctx* bcbuf;
    221     luaL_Buffer b;
    222     ap_directive_t **current = mconfig;
    223     struct cr_ctx ctx[1];
    224     int result;
    225     const char *filename = apr_psprintf(cmd->pool, "@%s", cmd->config_file->name);
    226     // get a word argument
    227     const char *word;
    228     apr_size_t wordlen;
    229     lua_State *lvm = get_luastate();
    230 
    231     word = ap_getword_conf(cmd->pool, &arg);
    232     wordlen = strlen(word);
    233     do {
    234         if (wordlen) {
    235             if (word[wordlen - 1] == '>') {
    236                 --wordlen;
    237                 break;
    238             }
    239             if (*arg == '>') break;
    240         }
    241         return apr_pstrcat(cmd->pool, "<", LUACMD, "> takes exactly one argument", NULL);
    242     } while (0);
    243 
    244     ctx->cfp = cmd->config_file;
    245     ctx->startline = cmd->config_file->line_number;
    246     lua_settop(lvm, 0);
    247     result = lua_load(lvm, direct_chunkreader, ctx, filename);
    248 
    249     if (result != 0) {
    250         word = apr_pstrcat(cmd->pool, "Lua Error:", lua_tostring(lvm, -1), NULL);
    251         lua_close(lvm);
    252         return word;
    253     }
    254     else {
    255         luaL_buffinit(lvm, &b);
    256         lua_dump(lvm, ldump_writer, &b);
    257         luaL_pushresult(&b);
    258         bytecode = lua_tostring(lvm, -1);
    259         bytecode_len = lua_strlen(lvm, -1);
    260     }
    261    
    262     /* Here, we have to replace our current config node for the next pass */
    263     if (!*current) {
    264         *current = apr_pcalloc(cmd->pool, sizeof(**current));
    265     }
    266    
    267     (*current)->filename = cmd->config_file->name;
    268     (*current)->line_num = ctx->startline;
    269     (*current)->directive = apr_pstrdup(cmd->pool, "GnuTLSRequireByteCode");
    270     (*current)->args = NULL;
    271 
    272     bcbuf = apr_pcalloc(cmd->pool, sizeof(bcbuf));
    273     bcbuf->buflen = bytecode_len;
    274     bcbuf->buf = apr_pstrmemdup(cmd->pool, bytecode, bytecode_len);
    275 
    276     (*current)->data = bcbuf;
    277     lua_close(lvm);
    278     return NULL;
    279 }
    280 
    281 const char *mgs_set_require_bytecode(cmd_parms *cmd, void *mconfig, const char *arg)
    282 {
    283     bcbuf_ctx* bcbuf;
    284     ap_directive_t *directive = cmd->directive;
    285     mgs_dirconf_rec *dc = mconfig;
    286 
    287     bcbuf = directive->data;
    288     dc->lua_bytecode_len = bcbuf->buflen;
    289     dc->lua_bytecode = apr_pstrmemdup(cmd->pool, bcbuf->buf, bcbuf->buflen);
    290    
    291     return NULL;
    292 }
     225const char *mgs_set_require_section(cmd_parms * cmd, void *mconfig,
     226                                    const char *arg)
     227{
     228        apr_size_t bytecode_len;
     229        const char *bytecode;
     230        bcbuf_ctx *bcbuf;
     231        luaL_Buffer b;
     232        ap_directive_t **current = mconfig;
     233        struct cr_ctx ctx[1];
     234        int result;
     235        const char *filename =
     236            apr_psprintf(cmd->pool, "@%s", cmd->config_file->name);
     237        // get a word argument
     238        const char *word;
     239        apr_size_t wordlen;
     240        lua_State *lvm = get_luastate();
     241
     242        word = ap_getword_conf(cmd->pool, &arg);
     243        wordlen = strlen(word);
     244        do {
     245                if (wordlen) {
     246                        if (word[wordlen - 1] == '>') {
     247                                --wordlen;
     248                                break;
     249                        }
     250                        if (*arg == '>')
     251                                break;
     252                }
     253                return apr_pstrcat(cmd->pool, "<", LUACMD,
     254                                   "> takes exactly one argument", NULL);
     255        } while (0);
     256
     257        ctx->cfp = cmd->config_file;
     258        ctx->startline = cmd->config_file->line_number;
     259        lua_settop(lvm, 0);
     260        result = lua_load(lvm, direct_chunkreader, ctx, filename);
     261
     262        if (result != 0) {
     263                word =
     264                    apr_pstrcat(cmd->pool, "Lua Error:",
     265                                lua_tostring(lvm, -1), NULL);
     266                lua_close(lvm);
     267                return word;
     268        } else {
     269                luaL_buffinit(lvm, &b);
     270                lua_dump(lvm, ldump_writer, &b);
     271                luaL_pushresult(&b);
     272                bytecode = lua_tostring(lvm, -1);
     273                bytecode_len = lua_strlen(lvm, -1);
     274        }
     275
     276        /* Here, we have to replace our current config node for the next pass */
     277        if (!*current) {
     278                *current = apr_pcalloc(cmd->pool, sizeof(**current));
     279        }
     280
     281        (*current)->filename = cmd->config_file->name;
     282        (*current)->line_num = ctx->startline;
     283        (*current)->directive =
     284            apr_pstrdup(cmd->pool, "GnuTLSRequireByteCode");
     285        (*current)->args = NULL;
     286
     287        bcbuf = apr_pcalloc(cmd->pool, sizeof(bcbuf));
     288        bcbuf->buflen = bytecode_len;
     289        bcbuf->buf = apr_pstrmemdup(cmd->pool, bytecode, bytecode_len);
     290
     291        (*current)->data = bcbuf;
     292        lua_close(lvm);
     293        return NULL;
     294}
     295
     296const char *mgs_set_require_bytecode(cmd_parms * cmd, void *mconfig,
     297                                     const char *arg)
     298{
     299        bcbuf_ctx *bcbuf;
     300        ap_directive_t *directive = cmd->directive;
     301        mgs_dirconf_rec *dc = mconfig;
     302
     303        bcbuf = directive->data;
     304        dc->lua_bytecode_len = bcbuf->buflen;
     305        dc->lua_bytecode =
     306            apr_pstrmemdup(cmd->pool, bcbuf->buf, bcbuf->buflen);
     307
     308        return NULL;
     309}
Note: See TracChangeset for help on using the changeset viewer.