Fossil

Check-in [68e6b07e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the 'nonce' command to TH1. Improve clarity of the 'default_csp' variable handling and add comments.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | dynamicCsp
Files: files | file ages | folders
SHA3-256: 68e6b07ebaf1ba674345311ca28bd1a7caae21566449a62a8f3d81ccfa65cdf8
User & Date: mistachkin 2019-02-17 07:16:26.811
Context
2019-02-17
07:47
Make sure the TH1 interp is available before trying to use it. ... (Closed-Leaf check-in: 600accbe user: mistachkin tags: dynamicCsp)
07:16
Add the 'nonce' command to TH1. Improve clarity of the 'default_csp' variable handling and add comments. ... (check-in: 68e6b07e user: mistachkin tags: dynamicCsp)
06:18
Skip setting the 'default_csp' TH1 variable if it already exists (e.g. it was manually overridden via the TH1 setup script). ... (check-in: 0b885bb9 user: mistachkin tags: dynamicCsp)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/style.c.
403
404
405
406
407
408
409
410

411
412
413
414
415

416
417
418
419
420
421
422
423






424
425
426
427
428
429
430
;

/*
** Initialize all the default TH1 variables
*/
static void style_init_th1_vars(const char *zTitle){
  const char *zNonce = style_nonce();
  Th_Store("nonce", zNonce);

  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
  Th_Store("project_description", db_get("project-description",""));
  if( zTitle ) Th_Store("title", zTitle);
  Th_Store("baseurl", g.zBaseURL);
  Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);

  if( !Th_ExistsVar(g.interp, "default_csp", -1) ){
    char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; "
                                     "script-src 'self' 'nonce-%s' ; "
                                     "style-src 'self' 'unsafe-inline'",
                                     zNonce);
    Th_Store("default_csp", zDfltCsp);
    sqlite3_free(zDfltCsp);
  }






  Th_Store("home", g.zTop);
  Th_Store("index_page", db_get("index-page","/home"));
  if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
  Th_Store("current_page", local_zCurrentPage);
  Th_Store("csrf_token", g.zCsrfToken);
  Th_Store("release_version", RELEASE_VERSION);
  Th_Store("manifest_version", MANIFEST_VERSION);







<
>
|
|
|
<
<
>








>
>
>
>
>
>







403
404
405
406
407
408
409

410
411
412
413


414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
;

/*
** Initialize all the default TH1 variables
*/
static void style_init_th1_vars(const char *zTitle){
  const char *zNonce = style_nonce();

  /*
  ** Do not overwrite the TH1 variable "default_csp" if it exists, as this
  ** allows it to be properly overridden via the TH1 setup script (i.e. it
  ** is evaluated before the header is rendered).


  */
  if( !Th_ExistsVar(g.interp, "default_csp", -1) ){
    char *zDfltCsp = sqlite3_mprintf("default-src 'self' data: ; "
                                     "script-src 'self' 'nonce-%s' ; "
                                     "style-src 'self' 'unsafe-inline'",
                                     zNonce);
    Th_Store("default_csp", zDfltCsp);
    sqlite3_free(zDfltCsp);
  }
  Th_Store("nonce", zNonce);
  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
  Th_Store("project_description", db_get("project-description",""));
  if( zTitle ) Th_Store("title", zTitle);
  Th_Store("baseurl", g.zBaseURL);
  Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
  Th_Store("home", g.zTop);
  Th_Store("index_page", db_get("index-page","/home"));
  if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath);
  Th_Store("current_page", local_zCurrentPage);
  Th_Store("csrf_token", g.zCsrfToken);
  Th_Store("release_version", RELEASE_VERSION);
  Th_Store("manifest_version", MANIFEST_VERSION);
Changes to src/th_main.c.
409
410
411
412
413
414
415




















416
417
418
419
420
421
422
      manifest_destroy(pManifest);
      return rid;
    }
  }
  Th_SetResult(interp, "file name not found in manifest", -1);
  return 0;
}





















/*
** TH1 command: puts STRING
** TH1 command: html STRING
**
** Output STRING escaped for HTML (puts) or unchanged (html).
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
      manifest_destroy(pManifest);
      return rid;
    }
  }
  Th_SetResult(interp, "file name not found in manifest", -1);
  return 0;
}

/*
** TH1 command: nonce
**
** Returns the value of the cryptographic nonce for the request being
** processed.
*/
static int nonceCmd(
  Th_Interp *interp,
  void *pConvert,
  int argc,
  const char **argv,
  int *argl
){
  if( argc!=1 ){
    return Th_WrongNumArgs(interp, "nonce");
  }
  Th_SetResult(interp, style_nonce(), -1);
  return TH_OK;
}

/*
** TH1 command: puts STRING
** TH1 command: html STRING
**
** Output STRING escaped for HTML (puts) or unchanged (html).
*/
2019
2020
2021
2022
2023
2024
2025

2026
2027
2028
2029
2030
2031
2032
    {"hasfeature",    hasfeatureCmd,        0},
    {"html",          putsCmd,              (void*)&aFlags[0]},
    {"htmlize",       htmlizeCmd,           0},
    {"http",          httpCmd,              0},
    {"insertCsrf",    insertCsrfCmd,        0},
    {"linecount",     linecntCmd,           0},
    {"markdown",      markdownCmd,          0},

    {"puts",          putsCmd,              (void*)&aFlags[1]},
    {"query",         queryCmd,             0},
    {"randhex",       randhexCmd,           0},
    {"redirect",      redirectCmd,          0},
    {"regexp",        regexpCmd,            0},
    {"reinitialize",  reinitializeCmd,      0},
    {"render",        renderCmd,            0},







>







2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
    {"hasfeature",    hasfeatureCmd,        0},
    {"html",          putsCmd,              (void*)&aFlags[0]},
    {"htmlize",       htmlizeCmd,           0},
    {"http",          httpCmd,              0},
    {"insertCsrf",    insertCsrfCmd,        0},
    {"linecount",     linecntCmd,           0},
    {"markdown",      markdownCmd,          0},
    {"nonce",         nonceCmd,             0},
    {"puts",          putsCmd,              (void*)&aFlags[1]},
    {"query",         queryCmd,             0},
    {"randhex",       randhexCmd,           0},
    {"redirect",      redirectCmd,          0},
    {"regexp",        regexpCmd,            0},
    {"reinitialize",  reinitializeCmd,      0},
    {"render",        renderCmd,            0},
Changes to test/th1.test.
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
fossil test-th-eval "info commands"
set sorted_result [lsort $RESULT]
protOut "Sorted: $sorted_result"
set base_commands {anoncap anycap array artifact break breakpoint catch\
      cgiHeaderLine checkout combobox continue date decorate dir enable_output \
      encode64 error expr for getParameter glob_match globalState hascap \
      hasfeature html htmlize http httpize if info insertCsrf lindex linecount \
      list llength lsearch markdown proc puts query randhex redirect regexp\
      reinitialize rename render repository return searchable set\
      setParameter setting stime string styleFooter styleHeader styleScript\
      tclReady trace unset unversioned uplevel upvar utime verifyCsrf wiki}
set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe}
if {$th1Tcl} {
  test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]}
} else {
  test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]}
}


###############################################################################

fossil test-th-eval "info vars"

if {$th1Hooks} {
  test th1-info-vars-1 {[lsort $RESULT] eq \







|
|








<







1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
fossil test-th-eval "info commands"
set sorted_result [lsort $RESULT]
protOut "Sorted: $sorted_result"
set base_commands {anoncap anycap array artifact break breakpoint catch\
      cgiHeaderLine checkout combobox continue date decorate dir enable_output \
      encode64 error expr for getParameter glob_match globalState hascap \
      hasfeature html htmlize http httpize if info insertCsrf lindex linecount \
      list llength lsearch markdown nonce proc puts query randhex redirect\
      regexp reinitialize rename render repository return searchable set\
      setParameter setting stime string styleFooter styleHeader styleScript\
      tclReady trace unset unversioned uplevel upvar utime verifyCsrf wiki}
set tcl_commands {tclEval tclExpr tclInvoke tclIsSafe tclMakeSafe}
if {$th1Tcl} {
  test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands $tcl_commands"]}
} else {
  test th1-info-commands-1 {$sorted_result eq [lsort "$base_commands"]}
}


###############################################################################

fossil test-th-eval "info vars"

if {$th1Hooks} {
  test th1-info-vars-1 {[lsort $RESULT] eq \
Changes to www/th1.md.
185
186
187
188
189
190
191

192
193
194
195
196
197
198
  *  html
  *  htmlize
  *  http
  *  httpize
  *  insertCsrf
  *  linecount
  *  markdown

  *  puts
  *  query
  *  randhex
  *  redirect
  *  regexp
  *  reinitialize
  *  render







>







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  *  html
  *  htmlize
  *  http
  *  httpize
  *  insertCsrf
  *  linecount
  *  markdown
  *  nonce
  *  puts
  *  query
  *  randhex
  *  redirect
  *  regexp
  *  reinitialize
  *  render
451
452
453
454
455
456
457







458
459
460
461
462
463
464

  *  markdown STRING

Renders the input string as markdown.  The result is a two-element list.
The first element contains the body, rendered as HTML.  The second element
is the text-only title string.








<a name="puts"></a>TH1 puts Command
-----------------------------------

  *  puts STRING

Outputs the STRING unchanged.








>
>
>
>
>
>
>







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

  *  markdown STRING

Renders the input string as markdown.  The result is a two-element list.
The first element contains the body, rendered as HTML.  The second element
is the text-only title string.

<a name="nonce"></a>TH1 nonce Command
-------------------------------------

  *  nonce

Returns the value of the cryptographic nonce for the request being processed.

<a name="puts"></a>TH1 puts Command
-----------------------------------

  *  puts STRING

Outputs the STRING unchanged.