Fossil SCM
Improvements to the new security-audit feature that shows the command-line that launched the process that generated the web page.
Commit
5caa3c5cebd37afb0c43bb82b25a4fa48f476562c5cf11d930c87552ad4bf494
Parent
5ab5469adf29bfa…
2 files changed
+9
-2
+8
-5
+9
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -136,10 +136,11 @@ | ||
| 136 | 136 | }; |
| 137 | 137 | #endif |
| 138 | 138 | |
| 139 | 139 | struct Global { |
| 140 | 140 | int argc; char **argv; /* Command-line arguments to the program */ |
| 141 | + char **argvOrig; /* Original g.argv prior to removing options */ | |
| 141 | 142 | char *nameOfExe; /* Full path of executable. */ |
| 142 | 143 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 143 | 144 | const char *zPhase; /* Phase of operation, for use by the error log |
| 144 | 145 | ** and for deriving $canonical_page TH1 variable */ |
| 145 | 146 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -444,11 +445,15 @@ | ||
| 444 | 445 | ** introduces some weird corner cases, as covered in forum thread |
| 445 | 446 | ** 4382bbc66757c39f. e.g. (fossil -U -- --args ...) is handled |
| 446 | 447 | ** differently when we stop at "--" here. */ |
| 447 | 448 | if( fossil_strcmp(z, "args")==0 ) break; |
| 448 | 449 | } |
| 449 | - if( (int)i>=g.argc-1 ) return; | |
| 450 | + if( (int)i>=g.argc-1 ){ | |
| 451 | + g.argvOrig = fossil_malloc( sizeof(char*)*(g.argc+1) ); | |
| 452 | + memcpy(g.argvOrig, g.argv, sizeof(g.argv[0])*(g.argc+1)); | |
| 453 | + return; | |
| 454 | + } | |
| 450 | 455 | |
| 451 | 456 | zFileName = g.argv[i+1]; |
| 452 | 457 | if( strcmp(zFileName,"-")==0 ){ |
| 453 | 458 | inFile = stdin; |
| 454 | 459 | }else if( !file_isfile(zFileName, ExtFILE) ){ |
| @@ -467,11 +472,11 @@ | ||
| 467 | 472 | blob_to_utf8_no_bom(&file, 1); |
| 468 | 473 | z = blob_str(&file); |
| 469 | 474 | for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++; |
| 470 | 475 | if( nLine>100000000 ) fossil_fatal("too many command-line arguments"); |
| 471 | 476 | nArg = g.argc + nLine*2; |
| 472 | - newArgv = fossil_malloc( sizeof(char*)*nArg ); | |
| 477 | + newArgv = fossil_malloc( sizeof(char*)*nArg*2 + 2); | |
| 473 | 478 | for(j=0; j<i; j++) newArgv[j] = g.argv[j]; |
| 474 | 479 | |
| 475 | 480 | blob_rewind(&file); |
| 476 | 481 | while( nLine-->0 && (n = blob_line(&file, &line))>0 ){ |
| 477 | 482 | /* Reminder: ^^^ nLine check avoids that embedded NUL bytes in the |
| @@ -510,10 +515,12 @@ | ||
| 510 | 515 | i += 2; |
| 511 | 516 | while( (int)i<g.argc ) newArgv[j++] = g.argv[i++]; |
| 512 | 517 | newArgv[j] = 0; |
| 513 | 518 | g.argc = j; |
| 514 | 519 | g.argv = newArgv; |
| 520 | + g.argvOrig = &g.argv[j+1]; | |
| 521 | + memcpy(g.argvOrig, g.argv, sizeof(g.argv[0])*(j+1)); | |
| 515 | 522 | } |
| 516 | 523 | |
| 517 | 524 | #ifdef FOSSIL_ENABLE_TCL |
| 518 | 525 | /* |
| 519 | 526 | ** Make a deep copy of the provided argument array and return it. |
| 520 | 527 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -136,10 +136,11 @@ | |
| 136 | }; |
| 137 | #endif |
| 138 | |
| 139 | struct Global { |
| 140 | int argc; char **argv; /* Command-line arguments to the program */ |
| 141 | char *nameOfExe; /* Full path of executable. */ |
| 142 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 143 | const char *zPhase; /* Phase of operation, for use by the error log |
| 144 | ** and for deriving $canonical_page TH1 variable */ |
| 145 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -444,11 +445,15 @@ | |
| 444 | ** introduces some weird corner cases, as covered in forum thread |
| 445 | ** 4382bbc66757c39f. e.g. (fossil -U -- --args ...) is handled |
| 446 | ** differently when we stop at "--" here. */ |
| 447 | if( fossil_strcmp(z, "args")==0 ) break; |
| 448 | } |
| 449 | if( (int)i>=g.argc-1 ) return; |
| 450 | |
| 451 | zFileName = g.argv[i+1]; |
| 452 | if( strcmp(zFileName,"-")==0 ){ |
| 453 | inFile = stdin; |
| 454 | }else if( !file_isfile(zFileName, ExtFILE) ){ |
| @@ -467,11 +472,11 @@ | |
| 467 | blob_to_utf8_no_bom(&file, 1); |
| 468 | z = blob_str(&file); |
| 469 | for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++; |
| 470 | if( nLine>100000000 ) fossil_fatal("too many command-line arguments"); |
| 471 | nArg = g.argc + nLine*2; |
| 472 | newArgv = fossil_malloc( sizeof(char*)*nArg ); |
| 473 | for(j=0; j<i; j++) newArgv[j] = g.argv[j]; |
| 474 | |
| 475 | blob_rewind(&file); |
| 476 | while( nLine-->0 && (n = blob_line(&file, &line))>0 ){ |
| 477 | /* Reminder: ^^^ nLine check avoids that embedded NUL bytes in the |
| @@ -510,10 +515,12 @@ | |
| 510 | i += 2; |
| 511 | while( (int)i<g.argc ) newArgv[j++] = g.argv[i++]; |
| 512 | newArgv[j] = 0; |
| 513 | g.argc = j; |
| 514 | g.argv = newArgv; |
| 515 | } |
| 516 | |
| 517 | #ifdef FOSSIL_ENABLE_TCL |
| 518 | /* |
| 519 | ** Make a deep copy of the provided argument array and return it. |
| 520 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -136,10 +136,11 @@ | |
| 136 | }; |
| 137 | #endif |
| 138 | |
| 139 | struct Global { |
| 140 | int argc; char **argv; /* Command-line arguments to the program */ |
| 141 | char **argvOrig; /* Original g.argv prior to removing options */ |
| 142 | char *nameOfExe; /* Full path of executable. */ |
| 143 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 144 | const char *zPhase; /* Phase of operation, for use by the error log |
| 145 | ** and for deriving $canonical_page TH1 variable */ |
| 146 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -444,11 +445,15 @@ | |
| 445 | ** introduces some weird corner cases, as covered in forum thread |
| 446 | ** 4382bbc66757c39f. e.g. (fossil -U -- --args ...) is handled |
| 447 | ** differently when we stop at "--" here. */ |
| 448 | if( fossil_strcmp(z, "args")==0 ) break; |
| 449 | } |
| 450 | if( (int)i>=g.argc-1 ){ |
| 451 | g.argvOrig = fossil_malloc( sizeof(char*)*(g.argc+1) ); |
| 452 | memcpy(g.argvOrig, g.argv, sizeof(g.argv[0])*(g.argc+1)); |
| 453 | return; |
| 454 | } |
| 455 | |
| 456 | zFileName = g.argv[i+1]; |
| 457 | if( strcmp(zFileName,"-")==0 ){ |
| 458 | inFile = stdin; |
| 459 | }else if( !file_isfile(zFileName, ExtFILE) ){ |
| @@ -467,11 +472,11 @@ | |
| 472 | blob_to_utf8_no_bom(&file, 1); |
| 473 | z = blob_str(&file); |
| 474 | for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++; |
| 475 | if( nLine>100000000 ) fossil_fatal("too many command-line arguments"); |
| 476 | nArg = g.argc + nLine*2; |
| 477 | newArgv = fossil_malloc( sizeof(char*)*nArg*2 + 2); |
| 478 | for(j=0; j<i; j++) newArgv[j] = g.argv[j]; |
| 479 | |
| 480 | blob_rewind(&file); |
| 481 | while( nLine-->0 && (n = blob_line(&file, &line))>0 ){ |
| 482 | /* Reminder: ^^^ nLine check avoids that embedded NUL bytes in the |
| @@ -510,10 +515,12 @@ | |
| 515 | i += 2; |
| 516 | while( (int)i<g.argc ) newArgv[j++] = g.argv[i++]; |
| 517 | newArgv[j] = 0; |
| 518 | g.argc = j; |
| 519 | g.argv = newArgv; |
| 520 | g.argvOrig = &g.argv[j+1]; |
| 521 | memcpy(g.argvOrig, g.argv, sizeof(g.argv[0])*(j+1)); |
| 522 | } |
| 523 | |
| 524 | #ifdef FOSSIL_ENABLE_TCL |
| 525 | /* |
| 526 | ** Make a deep copy of the provided argument array and return it. |
| 527 |
+8
-5
| --- src/security_audit.c | ||
| +++ src/security_audit.c | ||
| @@ -100,10 +100,11 @@ | ||
| 100 | 100 | const char *zReadCap; /* Capabilities of user group "reader" */ |
| 101 | 101 | const char *zPubPages; /* GLOB pattern for public pages */ |
| 102 | 102 | const char *zSelfCap; /* Capabilities of self-registered users */ |
| 103 | 103 | int hasSelfReg = 0; /* True if able to self-register */ |
| 104 | 104 | const char *zPublicUrl; /* Canonical access URL */ |
| 105 | + Blob cmd; | |
| 105 | 106 | char *z; |
| 106 | 107 | int n, i; |
| 107 | 108 | CapabilityString *pCap; |
| 108 | 109 | char **azCSP; /* Parsed content security policy */ |
| 109 | 110 | |
| @@ -692,18 +693,20 @@ | ||
| 692 | 693 | @ </p> |
| 693 | 694 | table_of_public_phantoms(); |
| 694 | 695 | @ </li> |
| 695 | 696 | } |
| 696 | 697 | |
| 698 | + blob_init(&cmd, 0, 0); | |
| 699 | + for(i=0; g.argvOrig[i]!=0; i++){ | |
| 700 | + blob_append_escaped_arg(&cmd, g.argvOrig[i], 0); | |
| 701 | + } | |
| 697 | 702 | @ <li><p> |
| 698 | - @ The command that generated this page was: | |
| 703 | + @ The command that generated this page: | |
| 699 | 704 | @ <blockquote> |
| 700 | - for(i=0; i<g.argc; i++){ | |
| 701 | - @ %h(g.argv[i]) \ | |
| 702 | - } | |
| 703 | - @ | |
| 705 | + @ <tt>%h(blob_str(&cmd))</tt> | |
| 704 | 706 | @ </blockquote></li> |
| 707 | + blob_zero(&cmd); | |
| 705 | 708 | |
| 706 | 709 | @ </ol> |
| 707 | 710 | style_finish_page(); |
| 708 | 711 | } |
| 709 | 712 | |
| 710 | 713 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -100,10 +100,11 @@ | |
| 100 | const char *zReadCap; /* Capabilities of user group "reader" */ |
| 101 | const char *zPubPages; /* GLOB pattern for public pages */ |
| 102 | const char *zSelfCap; /* Capabilities of self-registered users */ |
| 103 | int hasSelfReg = 0; /* True if able to self-register */ |
| 104 | const char *zPublicUrl; /* Canonical access URL */ |
| 105 | char *z; |
| 106 | int n, i; |
| 107 | CapabilityString *pCap; |
| 108 | char **azCSP; /* Parsed content security policy */ |
| 109 | |
| @@ -692,18 +693,20 @@ | |
| 692 | @ </p> |
| 693 | table_of_public_phantoms(); |
| 694 | @ </li> |
| 695 | } |
| 696 | |
| 697 | @ <li><p> |
| 698 | @ The command that generated this page was: |
| 699 | @ <blockquote> |
| 700 | for(i=0; i<g.argc; i++){ |
| 701 | @ %h(g.argv[i]) \ |
| 702 | } |
| 703 | @ |
| 704 | @ </blockquote></li> |
| 705 | |
| 706 | @ </ol> |
| 707 | style_finish_page(); |
| 708 | } |
| 709 | |
| 710 |
| --- src/security_audit.c | |
| +++ src/security_audit.c | |
| @@ -100,10 +100,11 @@ | |
| 100 | const char *zReadCap; /* Capabilities of user group "reader" */ |
| 101 | const char *zPubPages; /* GLOB pattern for public pages */ |
| 102 | const char *zSelfCap; /* Capabilities of self-registered users */ |
| 103 | int hasSelfReg = 0; /* True if able to self-register */ |
| 104 | const char *zPublicUrl; /* Canonical access URL */ |
| 105 | Blob cmd; |
| 106 | char *z; |
| 107 | int n, i; |
| 108 | CapabilityString *pCap; |
| 109 | char **azCSP; /* Parsed content security policy */ |
| 110 | |
| @@ -692,18 +693,20 @@ | |
| 693 | @ </p> |
| 694 | table_of_public_phantoms(); |
| 695 | @ </li> |
| 696 | } |
| 697 | |
| 698 | blob_init(&cmd, 0, 0); |
| 699 | for(i=0; g.argvOrig[i]!=0; i++){ |
| 700 | blob_append_escaped_arg(&cmd, g.argvOrig[i], 0); |
| 701 | } |
| 702 | @ <li><p> |
| 703 | @ The command that generated this page: |
| 704 | @ <blockquote> |
| 705 | @ <tt>%h(blob_str(&cmd))</tt> |
| 706 | @ </blockquote></li> |
| 707 | blob_zero(&cmd); |
| 708 | |
| 709 | @ </ol> |
| 710 | style_finish_page(); |
| 711 | } |
| 712 | |
| 713 |