Fossil

Check-in [8429f8a3df]
Login

Check-in [8429f8a3df]

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

Overview
Comment:Add support for --tls on the "fossil http" command.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ssl-server
Files: files | file ages | folders
SHA3-256: 8429f8a3df60ba1227373afee23cba40593d94b716d5912c1f4ab4e2ade97de9
User & Date: drh 2021-12-28 14:45:35.744
Context
2021-12-28
18:17
Fix the --files option on "fossil http" so that if a glob pattern does not begin with '*' then it will match beginning with the "/" of the PATH_INFO. ... (check-in: 5ac65aa496 user: drh tags: ssl-server)
14:45
Add support for --tls on the "fossil http" command. ... (check-in: 8429f8a3df user: drh tags: ssl-server)
2021-12-27
21:43
Sanitize the pathname on the /.well-known webpage. [forum:/forumpost/ba46d8e333|Forum post ba46d8e333]. ... (check-in: b265013b66 user: drh tags: ssl-server)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
2554
2555
2556
2557
2558
2559
2560



















2561
2562
2563
2564
2565
2566
2567
        return;
      }
    }
  }
#endif
  @ %d(GETPID())
}




















/*
** COMMAND: http*
**
** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
**
** Handle a single HTTP request appearing on stdin.  The resulting webpage







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







2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
        return;
      }
    }
  }
#endif
  @ %d(GETPID())
}

/*
** Check for options to "fossil server" or "fossil ui" that imply that
** SSL should be used, and initialize the SSL decoder.
*/
static void decode_ssl_options(void){
#if FOSSIL_ENABLE_SSL
  const char *zCertFile = 0;
  zCertFile = find_option("tls-cert-file",0,1);
  if( zCertFile ){
    g.httpUseSSL = 1;
    ssl_init_server(zCertFile, zCertFile);
  }
  if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){
    g.httpUseSSL = 1;
    ssl_init_server(0,0);
  }
#endif
}

/*
** COMMAND: http*
**
** Usage: %fossil http ?REPOSITORY? ?OPTIONS?
**
** Handle a single HTTP request appearing on stdin.  The resulting webpage
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618


2619
2620

2621
2622
2623
2624
2625
2626
2627

2628
2629
2630

2631
2632
2633
2634
2635
2636
2637
2638
2639
** thus also no redirecting from http: to https: will take place.
**
** If the --localauth option is given, then automatic login is performed
** for requests coming from localhost, if the "localauth" setting is not
** enabled.
**
** Options:
**   --baseurl URL    base URL (useful with reverse proxies)
**   --chroot DIR     Use directory for chroot instead of repository path.
**   --ckout-alias N  Treat URIs of the form /doc/N/... as if they were
**                       /doc/ckout/...
**   --extroot DIR    document root for the /ext extension mechanism
**   --files GLOB     comma-separate glob patterns for static file to serve
**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --in FILE        Take input from FILE instead of standard input
**   --ipaddr ADDR    Assume the request comes from the given IP address
**   --jsmode MODE       Determine how JavaScript is delivered with pages.
**                       Mode can be one of:
**                          inline       All JavaScript is inserted inline at
**                                       one or more points in the HTML file.
**                          separate     Separate HTTP requests are made for
**                                       each JavaScript file.
**                          bundled      Groups JavaScript files into one or
**                                       more bundled requests which
**                                       concatenate scripts together.
**                       Depending on the needs of any given page, inline
**                       and bundled modes might result in a single
**                       amalgamated script or several, but both approaches
**                       result in fewer HTTP requests than the separate mode.
**   --localauth      enable automatic login for local connections


**   --nocompress     do not compress HTTP replies
**   --nodelay        omit backoffice processing if it would delay process exit

**   --nojail         drop root privilege but do not enter the chroot jail
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --out FILE       write results to FILE instead of to standard output
**   --repolist       If REPOSITORY is directory, URL "/" lists all repos
**   --scgi           Interpret input as SCGI rather than HTTP
**   --skin LABEL     Use override skin LABEL

**   --th-trace       trace TH1 execution (for debugging purposes)
**   --mainmenu FILE  Override the mainmenu config setting with the contents
**                    of the given file.

**   --usepidkey      Use saved encryption key from parent process.  This is
**                    only necessary when using SEE on Windows.
**
** See also: [[cgi]], [[server]], [[winsrv]]
*/
void cmd_http(void){
  const char *zIpAddr = 0;
  const char *zNotFound;
  const char *zHost;







|
|
|
|
|
|
|
|
|
|













|
>
>
|
|
>
|
|
|
|
|
|
|
>
|
|
<
>
|
|







2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652

2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
** thus also no redirecting from http: to https: will take place.
**
** If the --localauth option is given, then automatic login is performed
** for requests coming from localhost, if the "localauth" setting is not
** enabled.
**
** Options:
**   --baseurl URL       base URL (useful with reverse proxies)
**   --chroot DIR        Use directory for chroot instead of repository path.
**   --ckout-alias N     Treat URIs of the form /doc/N/... as if they were
**                          /doc/ckout/...
**   --extroot DIR       document root for the /ext extension mechanism
**   --files GLOB        comma-separate glob patterns for static file to serve
**   --host NAME         specify hostname of the server
**   --https             signal a request coming in via https
**   --in FILE           Take input from FILE instead of standard input
**   --ipaddr ADDR       Assume the request comes from the given IP address
**   --jsmode MODE       Determine how JavaScript is delivered with pages.
**                       Mode can be one of:
**                          inline       All JavaScript is inserted inline at
**                                       one or more points in the HTML file.
**                          separate     Separate HTTP requests are made for
**                                       each JavaScript file.
**                          bundled      Groups JavaScript files into one or
**                                       more bundled requests which
**                                       concatenate scripts together.
**                       Depending on the needs of any given page, inline
**                       and bundled modes might result in a single
**                       amalgamated script or several, but both approaches
**                       result in fewer HTTP requests than the separate mode.
**   --localauth         enable automatic login for local connections
**   --mainmenu FILE     Override the mainmenu config setting with the contents
**                       of the given file.
**   --nocompress        do not compress HTTP replies
**   --nodelay           omit backoffice processing if it would delay
**                       process exit
**   --nojail            drop root privilege but do not enter the chroot jail
**   --nossl             signal that no SSL connections are available
**   --notfound URL      use URL as "HTTP 404, object not found" page.
**   --out FILE          write results to FILE instead of to standard output
**   --repolist          If REPOSITORY is directory, URL "/" lists all repos
**   --scgi              Interpret input as SCGI rather than HTTP
**   --skin LABEL        Use override skin LABEL
**   --ssl               Use TLS (HTTPS) encryption.  Alias for --tls
**   --th-trace          trace TH1 execution (for debugging purposes)
**   --tls               Use TLS (HTTPS) encryption.

**   --tls-cert-file FN  Read the TLS certificate and private key from FN
**   --usepidkey         Use saved encryption key from parent process. This is
**                       only necessary when using SEE on Windows.
**
** See also: [[cgi]], [[server]], [[winsrv]]
*/
void cmd_http(void){
  const char *zIpAddr = 0;
  const char *zNotFound;
  const char *zHost;
2697
2698
2699
2700
2701
2702
2703

2704
2705
2706












2707
2708
2709
2710
2711
2712
2713
  }
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
  g.zMainMenuFile = find_option("mainmenu",0,1);
  if( g.zMainMenuFile!=0 && file_size(g.zMainMenuFile,ExtFILE)<0 ){
    fossil_fatal("Cannot read --mainmenu file %s", g.zMainMenuFile);
  }


  /* We should be done with options.. */
  verify_all_options();













  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
  g.cgiOutput = 1;
  g.fullHttpReply = 1;
  find_server_repository(2, 0);
  if( zIpAddr==0 ){
    zIpAddr = cgi_ssh_remote_addr(0);







>



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







2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
  }
  zHost = find_option("host", 0, 1);
  if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost);
  g.zMainMenuFile = find_option("mainmenu",0,1);
  if( g.zMainMenuFile!=0 && file_size(g.zMainMenuFile,ExtFILE)<0 ){
    fossil_fatal("Cannot read --mainmenu file %s", g.zMainMenuFile);
  }
  decode_ssl_options();

  /* We should be done with options.. */
  verify_all_options();
  if( g.httpUseSSL ){
    if( useSCGI ){
      fossil_fatal("SSL not (yet) supported for SCGI");
    }
    if( g.fSshClient & CGI_SSH_CLIENT ){
      fossil_fatal("SSL not compatible with SSH");
    }
    if( zInFile || zOutFile ){
      fossil_fatal("SSL usable only on a socket");
    }
    cgi_replace_parameter("HTTPS","on");
  }

  if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
  g.cgiOutput = 1;
  g.fullHttpReply = 1;
  find_server_repository(2, 0);
  if( zIpAddr==0 ){
    zIpAddr = cgi_ssh_remote_addr(0);
2721
2722
2723
2724
2725
2726
2727





2728
2729
2730






2731
2732
2733
2734
2735
2736
2737
    g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
  }
  if( useSCGI ){
    cgi_handle_scgi_request();
  }else if( g.fSshClient & CGI_SSH_CLIENT ){
    ssh_request_loop(zIpAddr, glob_create(zFileGlob));
  }else{





    cgi_handle_http_request(zIpAddr);
  }
  process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);






}

/*
** Process all requests in a single SSH connection if possible.
*/
void ssh_request_loop(const char *zIpAddr, Glob *FileGlob){
  blob_zero(&g.cgiIn);







>
>
>
>
>



>
>
>
>
>
>







2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
    g.zRepositoryName = enter_chroot_jail(g.zRepositoryName, noJail);
  }
  if( useSCGI ){
    cgi_handle_scgi_request();
  }else if( g.fSshClient & CGI_SSH_CLIENT ){
    ssh_request_loop(zIpAddr, glob_create(zFileGlob));
  }else{
#if FOSSIL_ENABLE_SSL
    if( g.httpUseSSL ){
      g.httpSSLConn = ssl_new_server(0,-1);
    }
#endif
    cgi_handle_http_request(zIpAddr);
  }
  process_one_web_page(zNotFound, glob_create(zFileGlob), allowRepoList);
#if FOSSIL_ENABLE_SSL
  if( g.httpUseSSL && g.httpSSLConn ){
    ssl_close_server(g.httpSSLConn);
    g.httpSSLConn = 0;
  }
#endif /* FOSSIL_ENABLE_SSL */
}

/*
** Process all requests in a single SSH connection if possible.
*/
void ssh_request_loop(const char *zIpAddr, Glob *FileGlob){
  blob_zero(&g.cgiIn);
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
** (2) Any call to sleep() or sqlite3_sleep() will cancel the alarm.
*/
void fossil_set_timeout(int N){
#ifndef _WIN32
  signal(SIGALRM, sigalrm_handler);
  alarm(N);
  nAlarmSeconds = N;
#endif
}

/*
** Check for options to "fossil server" or "fossil ui" that imply that
** SSL should be used, and initialize the SSL decoder.
*/
static void decode_ssl_options(void){
#if FOSSIL_ENABLE_SSL
  const char *zCertFile = 0;
  zCertFile = find_option("tls-cert-file",0,1);
  if( zCertFile ){
    g.httpUseSSL = 1;
    ssl_init_server(zCertFile, zCertFile);
  }
  if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){
    g.httpUseSSL = 1;
    ssl_init_server(0,0);
  }
#if !defined(_WIN32)
  if( db_get_int("redirect-to-https",0)==2 ){
    g.httpUseSSL = 1;
    ssl_init_server(0,0);
  }
#endif
#endif
}

/*
** COMMAND: server*
** COMMAND: ui
**







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2878
2879
2880
2881
2882
2883
2884

























2885
2886
2887
2888
2889
2890
2891
** (2) Any call to sleep() or sqlite3_sleep() will cancel the alarm.
*/
void fossil_set_timeout(int N){
#ifndef _WIN32
  signal(SIGALRM, sigalrm_handler);
  alarm(N);
  nAlarmSeconds = N;

























#endif
}

/*
** COMMAND: server*
** COMMAND: ui
**