comparison src/c/urweb.c @ 1877:22b44fe822bf

Take proper account of signatures changing during page generation
author Adam Chlipala <adam@chlipala.net>
date Thu, 10 Oct 2013 14:48:43 -0400
parents 216a3a67ebe3
children 0354df1b6849
comparison
equal deleted inserted replaced
1876:fdafa3f92e40 1877:22b44fe822bf
469 unsigned nextId; 469 unsigned nextId;
470 470
471 int amInitializing; 471 int amInitializing;
472 472
473 char error_message[ERROR_BUF_LEN]; 473 char error_message[ERROR_BUF_LEN];
474
475 int usedSig, needsResig;
474 }; 476 };
475 477
476 size_t uw_headers_max = SIZE_MAX; 478 size_t uw_headers_max = SIZE_MAX;
477 size_t uw_page_max = SIZE_MAX; 479 size_t uw_page_max = SIZE_MAX;
478 size_t uw_heap_max = SIZE_MAX; 480 size_t uw_heap_max = SIZE_MAX;
543 ctx->queryString = NULL; 545 ctx->queryString = NULL;
544 546
545 ctx->nextId = 0; 547 ctx->nextId = 0;
546 548
547 ctx->amInitializing = 0; 549 ctx->amInitializing = 0;
550
551 ctx->usedSig = 0;
552 ctx->needsResig = 0;
548 553
549 return ctx; 554 return ctx;
550 } 555 }
551 556
552 size_t uw_inputs_max = SIZE_MAX; 557 size_t uw_inputs_max = SIZE_MAX;
622 ctx->used_transactionals = 0; 627 ctx->used_transactionals = 0;
623 ctx->script_header = ""; 628 ctx->script_header = "";
624 ctx->queryString = NULL; 629 ctx->queryString = NULL;
625 ctx->nextId = 0; 630 ctx->nextId = 0;
626 ctx->amInitializing = 0; 631 ctx->amInitializing = 0;
632 ctx->usedSig = 0;
633 ctx->needsResig = 0;
627 } 634 }
628 635
629 void uw_reset_keep_request(uw_context ctx) { 636 void uw_reset_keep_request(uw_context ctx) {
630 uw_reset_keep_error_message(ctx); 637 uw_reset_keep_error_message(ctx);
631 ctx->error_message[0] = 0; 638 ctx->error_message[0] = 0;
3081 } 3088 }
3082 3089
3083 return NULL; 3090 return NULL;
3084 } 3091 }
3085 3092
3093 static void set_cookie(uw_context ctx) {
3094 if (ctx->usedSig)
3095 ctx->needsResig = 1;
3096 }
3097
3086 uw_unit uw_Basis_set_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c, uw_Basis_string v, uw_Basis_time *expires, uw_Basis_bool secure) { 3098 uw_unit uw_Basis_set_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c, uw_Basis_string v, uw_Basis_time *expires, uw_Basis_bool secure) {
3087 uw_write_header(ctx, "Set-Cookie: "); 3099 uw_write_header(ctx, "Set-Cookie: ");
3088 uw_write_header(ctx, c); 3100 uw_write_header(ctx, c);
3089 uw_write_header(ctx, "="); 3101 uw_write_header(ctx, "=");
3090 uw_write_header(ctx, v); 3102 uw_write_header(ctx, v);
3103 uw_write_header(ctx, formatted); 3115 uw_write_header(ctx, formatted);
3104 } 3116 }
3105 if (secure) 3117 if (secure)
3106 uw_write_header(ctx, "; secure"); 3118 uw_write_header(ctx, "; secure");
3107 uw_write_header(ctx, "\r\n"); 3119 uw_write_header(ctx, "\r\n");
3120 set_cookie(ctx);
3108 3121
3109 return uw_unit_v; 3122 return uw_unit_v;
3110 } 3123 }
3111 3124
3112 uw_unit uw_Basis_clear_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c) { 3125 uw_unit uw_Basis_clear_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c) {
3113 uw_write_header(ctx, "Set-Cookie: "); 3126 uw_write_header(ctx, "Set-Cookie: ");
3114 uw_write_header(ctx, c); 3127 uw_write_header(ctx, c);
3115 uw_write_header(ctx, "=; path="); 3128 uw_write_header(ctx, "=; path=");
3116 uw_write_header(ctx, prefix); 3129 uw_write_header(ctx, prefix);
3117 uw_write_header(ctx, "; " THE_PAST "\r\n"); 3130 uw_write_header(ctx, "; " THE_PAST "\r\n");
3131 set_cookie(ctx);
3118 3132
3119 return uw_unit_v; 3133 return uw_unit_v;
3120 } 3134 }
3121 3135
3122 size_t uw_deltas_max = SIZE_MAX; 3136 size_t uw_deltas_max = SIZE_MAX;
3190 return ctx->app ? ctx->app->db_rollback(ctx) : 0; 3204 return ctx->app ? ctx->app->db_rollback(ctx) : 0;
3191 } 3205 }
3192 3206
3193 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; 3207 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
3194 3208
3209 extern int uw_hash_blocksize;
3210
3211 static const char sig_intro[] = "<input type=\"hidden\" name=\"Sig\" value=\"";
3212
3213 static char *find_sig(char *haystack) {
3214 int i;
3215 char *s = strstr(haystack, sig_intro);
3216
3217 if (!s || strlen(haystack) - (s - haystack) - (sizeof sig_intro - 1) < uw_hash_blocksize*2+1)
3218 return NULL;
3219
3220 s += sizeof sig_intro - 1;
3221
3222 for (i = 0; i < uw_hash_blocksize*2; ++i)
3223 if (!isxdigit((int)s[i]))
3224 return NULL;
3225
3226 if (s[i] != '"')
3227 return NULL;
3228
3229 return s;
3230 }
3231
3195 void uw_commit(uw_context ctx) { 3232 void uw_commit(uw_context ctx) {
3196 int i; 3233 int i;
3234 char *sig;
3197 3235
3198 if (uw_has_error(ctx)) { 3236 if (uw_has_error(ctx)) {
3199 uw_rollback(ctx, 0); 3237 uw_rollback(ctx, 0);
3200 return; 3238 return;
3201 } 3239 }
3312 ctx->page.front += lenP; 3350 ctx->page.front += lenP;
3313 memcpy(start, "<head>", 6); 3351 memcpy(start, "<head>", 6);
3314 memcpy(start + 6, ctx->script_header, lenH); 3352 memcpy(start + 6, ctx->script_header, lenH);
3315 memcpy(start + 6 + lenH, "</head>", 7); 3353 memcpy(start + 6 + lenH, "</head>", 7);
3316 } 3354 }
3355 }
3356 }
3357
3358 if (ctx->needsResig) {
3359 sig = find_sig(ctx->page.start);
3360 if (sig) {
3361 char *realsig = ctx->app->cookie_sig(ctx);
3362
3363 do {
3364 memcpy(sig, realsig, 2*uw_hash_blocksize);
3365 sig = find_sig(sig);
3366 } while (sig);
3317 } 3367 }
3318 } 3368 }
3319 } 3369 }
3320 3370
3321 3371
3559 3609
3560 uw_Basis_string uw_unnull(uw_Basis_string s) { 3610 uw_Basis_string uw_unnull(uw_Basis_string s) {
3561 return s ? s : ""; 3611 return s ? s : "";
3562 } 3612 }
3563 3613
3564 extern int uw_hash_blocksize;
3565
3566 uw_Basis_string uw_Basis_makeSigString(uw_context ctx, uw_Basis_string sig) { 3614 uw_Basis_string uw_Basis_makeSigString(uw_context ctx, uw_Basis_string sig) {
3567 uw_Basis_string r = uw_malloc(ctx, 2 * uw_hash_blocksize + 1); 3615 uw_Basis_string r = uw_malloc(ctx, 2 * uw_hash_blocksize + 1);
3568 int i; 3616 int i;
3569 3617
3570 for (i = 0; i < uw_hash_blocksize; ++i) 3618 for (i = 0; i < uw_hash_blocksize; ++i)
3589 3637
3590 return x == 0; 3638 return x == 0;
3591 } 3639 }
3592 3640
3593 uw_Basis_string uw_Basis_sigString(uw_context ctx, uw_unit u) { 3641 uw_Basis_string uw_Basis_sigString(uw_context ctx, uw_unit u) {
3642 ctx->usedSig = 1;
3594 return ctx->app->cookie_sig(ctx); 3643 return ctx->app->cookie_sig(ctx);
3595 } 3644 }
3596 3645
3597 uw_Basis_string uw_Basis_fileName(uw_context ctx, uw_Basis_file f) { 3646 uw_Basis_string uw_Basis_fileName(uw_context ctx, uw_Basis_file f) {
3598 return f.name; 3647 return f.name;