Fossil

Check-in [02961b8078]
Login

Check-in [02961b8078]

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

Overview
Comment:Disable CSP for /chat with a ping= query parameter. This is a drastic measure to get the feature working. We can work on providing a better solution later.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 02961b80782e93931548889fa4833d40705d609b70df0964eaa3d9bc53a39043
User & Date: drh 2020-12-24 17:10:24.723
Context
2020-12-24
17:46
Fix a problem with web-browser launch on Windows for "fossil chat". ... (check-in: dcc854a98b user: drh tags: trunk)
17:10
Disable CSP for /chat with a ping= query parameter. This is a drastic measure to get the feature working. We can work on providing a better solution later. ... (check-in: 02961b8078 user: drh tags: trunk)
15:58
Fix a harmless compiler warning. ... (check-in: b4862238ec user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/chat.c.
87
88
89
90
91
92
93

94
95
96
97
98
99
100
  login_check_credentials();
  if( !g.perm.Chat ){
    login_needed(g.anon.Chat);
    return;
  }
  iPingTcp = atoi(PD("ping","0"));
  if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0;

  style_set_current_feature("chat");
  style_header("Chat");
  @ <style>
  @ #dialog {
  @  width: 97%%;
  @ }
  @ #chat-input-area {







>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  login_check_credentials();
  if( !g.perm.Chat ){
    login_needed(g.anon.Chat);
    return;
  }
  iPingTcp = atoi(PD("ping","0"));
  if( iPingTcp<1000 || iPingTcp>65535 ) iPingTcp = 0;
  if( iPingTcp ) style_disable_csp();
  style_set_current_feature("chat");
  style_header("Chat");
  @ <style>
  @ #dialog {
  @  width: 97%%;
  @ }
  @ #chat-input-area {
567
568
569
570
571
572
573

574
575
576
577
578
579
580
** at URL.  Or if URL is not specified, use the default remote repository.
** Event notifications on this session cause the U+0007 character to
** be sent to the TTY on which the "fossil chat" command is run, thus
** causing an auditory notification.
*/
void chat_command(void){
  const char *zUrl = 0;

  char *azArgv[5];
  db_find_and_open_repository(0,0);
  if( g.argc==3 ){
    zUrl = g.argv[2];
  }else if( g.argc!=2 ){
    usage("?URL?");
  }else{







>







568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
** at URL.  Or if URL is not specified, use the default remote repository.
** Event notifications on this session cause the U+0007 character to
** be sent to the TTY on which the "fossil chat" command is run, thus
** causing an auditory notification.
*/
void chat_command(void){
  const char *zUrl = 0;
  size_t i;
  char *azArgv[5];
  db_find_and_open_repository(0,0);
  if( g.argc==3 ){
    zUrl = g.argv[2];
  }else if( g.argc!=2 ){
    usage("?URL?");
  }else{
597
598
599
600
601
602
603


604
605
606
607
608
609
  }
  if( strncmp(zUrl,"http://",7)!=0 && strncmp("https://",zUrl,8)!=0 ){
    fossil_fatal("Not a valid URL: %s", zUrl);
  }
  azArgv[0] = g.argv[0];
  azArgv[1] = "ui";
  azArgv[2] = "--internal-chat-url";


  azArgv[3] = mprintf("%s/chat?ping=%%d", zUrl);
  azArgv[4] = 0;
  g.argv = azArgv;
  g.argc = 4;
  cmd_webserver();
}







>
>
|





599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
  }
  if( strncmp(zUrl,"http://",7)!=0 && strncmp("https://",zUrl,8)!=0 ){
    fossil_fatal("Not a valid URL: %s", zUrl);
  }
  azArgv[0] = g.argv[0];
  azArgv[1] = "ui";
  azArgv[2] = "--internal-chat-url";
  i = strlen(zUrl);
  if( i && zUrl[i-1]=='/' ) i--;
  azArgv[3] = mprintf("%.*s/chat?ping=%%d", i, zUrl);
  azArgv[4] = 0;
  g.argv = azArgv;
  g.argc = 4;
  cmd_webserver();
}
Changes to src/style.c.
82
83
84
85
86
87
88






89
90
91
92
93
94
95
static unsigned adUnitFlags = 0;

/*
** Submenu disable flag
*/
static int submenuEnable = 1;







/*
** Flags for various javascript files needed prior to </body>
*/
static int needHrefJs = 0;      /* href.js */

/*
** Extra JS added to the end of the file.







>
>
>
>
>
>







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
static unsigned adUnitFlags = 0;

/*
** Submenu disable flag
*/
static int submenuEnable = 1;

/*
** Disable content-security-policy.
** Warning:  Do not disable the CSP without careful consideration!
*/
static int disableCSP = 0;

/*
** Flags for various javascript files needed prior to </body>
*/
static int needHrefJs = 0;      /* href.js */

/*
** Extra JS added to the end of the file.
523
524
525
526
527
528
529
530
531
532
533
534


535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553











554
555
556
557
558
559
560
** should be released by the caller.
*/
char *style_csp(int toHeader){
  static const char zBackupCSP[] = 
   "default-src 'self' data:; "
   "script-src 'self' 'nonce-$nonce'; "
   "style-src 'self' 'unsafe-inline'";
  const char *zFormat = db_get("default-csp","");
  Blob csp;
  char *zNonce;
  char *zCsp;
  int i;


  if( zFormat[0]==0 ){
    zFormat = zBackupCSP;
  }
  blob_init(&csp, 0, 0);
  while( zFormat[0] && (zNonce = strstr(zFormat,"$nonce"))!=0 ){
    blob_append(&csp, zFormat, (int)(zNonce - zFormat));
    blob_append(&csp, style_nonce(), -1);
    zFormat = zNonce + 6;
  }
  blob_append(&csp, zFormat, -1);
  zCsp = blob_str(&csp);
  /* No whitespace other than actual space characters allowed in the CSP
  ** string.  See https://fossil-scm.org/forum/forumpost/d29e3af43c */
  for(i=0; zCsp[i]; i++){ if( fossil_isspace(zCsp[i]) ) zCsp[i] = ' '; }
  if( toHeader ){
    cgi_printf_header("Content-Security-Policy: %s\r\n", zCsp);
  }
  return zCsp;
}












/*
** Default HTML page header text through <body>.  If the repository-specific
** header template lacks a <body> tag, then all of the following is
** prepended.
*/
static const char zDfltHeader[] = 







|




>
>



















>
>
>
>
>
>
>
>
>
>
>







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
** should be released by the caller.
*/
char *style_csp(int toHeader){
  static const char zBackupCSP[] = 
   "default-src 'self' data:; "
   "script-src 'self' 'nonce-$nonce'; "
   "style-src 'self' 'unsafe-inline'";
  const char *zFormat;
  Blob csp;
  char *zNonce;
  char *zCsp;
  int i;
  if( disableCSP ) return fossil_strdup("");
  zFormat = db_get("default-csp","");
  if( zFormat[0]==0 ){
    zFormat = zBackupCSP;
  }
  blob_init(&csp, 0, 0);
  while( zFormat[0] && (zNonce = strstr(zFormat,"$nonce"))!=0 ){
    blob_append(&csp, zFormat, (int)(zNonce - zFormat));
    blob_append(&csp, style_nonce(), -1);
    zFormat = zNonce + 6;
  }
  blob_append(&csp, zFormat, -1);
  zCsp = blob_str(&csp);
  /* No whitespace other than actual space characters allowed in the CSP
  ** string.  See https://fossil-scm.org/forum/forumpost/d29e3af43c */
  for(i=0; zCsp[i]; i++){ if( fossil_isspace(zCsp[i]) ) zCsp[i] = ' '; }
  if( toHeader ){
    cgi_printf_header("Content-Security-Policy: %s\r\n", zCsp);
  }
  return zCsp;
}

/*
** Disable content security policy for the current page.
** WARNING:  Do not do this lightly!
**
** This routine must be called before the CSP is sued by 
** style_header().
*/
void style_disable_csp(void){
  disableCSP = 1;
}

/*
** Default HTML page header text through <body>.  If the repository-specific
** header template lacks a <body> tag, then all of the following is
** prepended.
*/
static const char zDfltHeader[] =