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