Fossil

Check-in [0600b278c0]
Login

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

Overview
Comment:Remove the unused inherit-anon configuration attribute. Fix the automatic redirect that follows a login operation. Fix "config push user" on the server side.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0600b278c0f105dc1aafaf7ee2decb84d3801607
User & Date: drh 2008-10-26 21:30:23.000
Context
2008-10-27
15:34
Fix the web-browser user setting so that it actually works. check-in: 3f5ef308fe user: drh tags: trunk
2008-10-26
21:30
Remove the unused inherit-anon configuration attribute. Fix the automatic redirect that follows a login operation. Fix "config push user" on the server side. check-in: 0600b278c0 user: drh tags: trunk
15:59
Correctly detect when an artifact prefix does not match any artifact. Provide better error messages for non-matching and ambiguous artifact prefixes. Fix for ticket [d0a7fc67e9]. check-in: 9acf0bcdbe user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
**                     If undefined, the internal text diff will be used.
**
**    editor           Text editor command used for check-in comments.
**
**    gdiff-command    External command to run when performing a graphical
**                     diff. If undefined, text diff will be used.
**
**    inherit-anon     If enabled, any web user inherits capabilities from
**                     anonymous as well as nobody.
**
**    localauth        If enabled, require that HTTP connections from
**                     127.0.0.1 be authenticated by password.  If
**                     false, all HTTP requests from localhost have
**                     unrestricted access to the repository.
**
**    clearsign        When enabled (the default), fossil will attempt to
**                     sign all commits with gpg.  When disabled, commits will







<
<
<







1201
1202
1203
1204
1205
1206
1207



1208
1209
1210
1211
1212
1213
1214
**                     If undefined, the internal text diff will be used.
**
**    editor           Text editor command used for check-in comments.
**
**    gdiff-command    External command to run when performing a graphical
**                     diff. If undefined, text diff will be used.
**



**    localauth        If enabled, require that HTTP connections from
**                     127.0.0.1 be authenticated by password.  If
**                     false, all HTTP requests from localhost have
**                     unrestricted access to the repository.
**
**    clearsign        When enabled (the default), fossil will attempt to
**                     sign all commits with gpg.  When disabled, commits will
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
*/
void setting_cmd(void){
  static const char *azName[] = {
    "autosync",
    "diff-command",
    "editor",
    "gdiff-command",
    "inherit-anon",
    "localauth",
    "clearsign",
    "pgp-command",
    "proxy",
    "web-browser",
  };
  int i;







<







1229
1230
1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
*/
void setting_cmd(void){
  static const char *azName[] = {
    "autosync",
    "diff-command",
    "editor",
    "gdiff-command",

    "localauth",
    "clearsign",
    "pgp-command",
    "proxy",
    "web-browser",
  };
  int i;
Changes to src/login.c.
62
63
64
65
66
67
68













69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    zCookieName = malloc( n*2+16 );
                      /* 0123456789 12345 */
    strcpy(zCookieName, "fossil_login_");
    encode16((unsigned char*)g.zTop, (unsigned char*)&zCookieName[13], n);
  }
  return zCookieName;
}














/*
** WEBPAGE: /login
** WEBPAGE: /logout
**
** Generate the login page
*/
void login_page(void){
  const char *zUsername, *zPasswd, *zGoto;
  const char *zNew1, *zNew2;
  const char *zAnonPw = 0;
  int anonFlag;
  char *zErrMsg = "";

  login_check_credentials();
  zUsername = P("u");
  zPasswd = P("p");
  zGoto = PD("g","index");
  anonFlag = P("anon")!=0;
  if( P("out")!=0 ){
    const char *zCookieName = login_cookie_name();
    cgi_set_cookie(zCookieName, "", 0, -86400);
    cgi_redirect(zGoto);
  }
  if( g.okPassword && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
    if( db_int(1, "SELECT 0 FROM user"
                  " WHERE uid=%d AND pw=%Q", g.userUid, zPasswd) ){
      sleep(1);
      zErrMsg = 
         @ <p><font color="red">







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








|








<




|







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
    zCookieName = malloc( n*2+16 );
                      /* 0123456789 12345 */
    strcpy(zCookieName, "fossil_login_");
    encode16((unsigned char*)g.zTop, (unsigned char*)&zCookieName[13], n);
  }
  return zCookieName;
}

/*
** Redirect to the page specified by the "g" query parameter.
** Or if there is no "g" query parameter, redirect to the homepage.
*/
static void redirect_to_g(void){
  const char *zGoto = P("g");
  if( zGoto ){
    cgi_redirect(zGoto);
  }else{
    fossil_redirect_home();
  }
}

/*
** WEBPAGE: /login
** WEBPAGE: /logout
**
** Generate the login page
*/
void login_page(void){
  const char *zUsername, *zPasswd;
  const char *zNew1, *zNew2;
  const char *zAnonPw = 0;
  int anonFlag;
  char *zErrMsg = "";

  login_check_credentials();
  zUsername = P("u");
  zPasswd = P("p");

  anonFlag = P("anon")!=0;
  if( P("out")!=0 ){
    const char *zCookieName = login_cookie_name();
    cgi_set_cookie(zCookieName, "", 0, -86400);
    redirect_to_g();
  }
  if( g.okPassword && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
    if( db_int(1, "SELECT 0 FROM user"
                  " WHERE uid=%d AND pw=%Q", g.userUid, zPasswd) ){
      sleep(1);
      zErrMsg = 
         @ <p><font color="red">
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
         @ Your password is unchanged.
         @ </font></p>
      ;
    }else{
      db_multi_exec(
         "UPDATE user SET pw=%Q WHERE uid=%d", zNew1, g.userUid
      );
      cgi_redirect(zGoto);
      return;
    }
  }
  if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){
    int uid = db_int(0,
        "SELECT uid FROM user"
        " WHERE login=%Q AND pw=%Q", zUsername, zPasswd);







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
         @ Your password is unchanged.
         @ </font></p>
      ;
    }else{
      db_multi_exec(
         "UPDATE user SET pw=%Q WHERE uid=%d", zNew1, g.userUid
      );
      redirect_to_g();
      return;
    }
  }
  if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){
    int uid = db_int(0,
        "SELECT uid FROM user"
        " WHERE login=%Q AND pw=%Q", zUsername, zPasswd);
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
        cgi_set_cookie(zCookieName, zCookie, 0, expires);
        db_multi_exec(
          "UPDATE user SET cookie=%Q, ipaddr=%Q, "
          "  cexpire=julianday('now')+%d/86400.0 WHERE uid=%d",
          zCookie, zIpAddr, expires, uid
        );
      }
      cgi_redirect(zGoto);
    }
  }
  style_header("Login/Logout");
  @ %s(zErrMsg)
  @ <form action="login" method="POST">
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))">







|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
        cgi_set_cookie(zCookieName, zCookie, 0, expires);
        db_multi_exec(
          "UPDATE user SET cookie=%Q, ipaddr=%Q, "
          "  cexpire=julianday('now')+%d/86400.0 WHERE uid=%d",
          zCookie, zIpAddr, expires, uid
        );
      }
      redirect_to_g();
    }
  }
  style_header("Login/Logout");
  @ %s(zErrMsg)
  @ <form action="login" method="POST">
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))">
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
** Set the global capability flags based on a capability string.
*/
void login_set_capabilities(const char *zCap){
  static char *zDev = 0;
  int i;
  for(i=0; zCap[i]; i++){
    switch( zCap[i] ){
      case 's':   g.okSetup = 1;
      case 'a':   g.okAdmin = g.okRdTkt = g.okWrTkt = 
                              g.okRdWiki = g.okWrWiki = g.okNewWiki =
                              g.okApndWiki = g.okHistory = g.okClone = 
                              g.okNewTkt = g.okPassword = g.okRdAddr =
                              g.okTktFmt = 1;
      case 'i':   g.okRead = g.okWrite = 1;                     break;
      case 'o':   g.okRead = 1;                                 break;
      case 'z':   g.okZip = 1;                                  break;

      case 'd':   g.okDelete = 1;                               break;
      case 'h':   g.okHistory = 1;                              break;
      case 'g':   g.okClone = 1;                                break;







|




|







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
** Set the global capability flags based on a capability string.
*/
void login_set_capabilities(const char *zCap){
  static char *zDev = 0;
  int i;
  for(i=0; zCap[i]; i++){
    switch( zCap[i] ){
      case 's':   g.okSetup = 1;  /* Fall thru into Admin */
      case 'a':   g.okAdmin = g.okRdTkt = g.okWrTkt = 
                              g.okRdWiki = g.okWrWiki = g.okNewWiki =
                              g.okApndWiki = g.okHistory = g.okClone = 
                              g.okNewTkt = g.okPassword = g.okRdAddr =
                              g.okTktFmt = 1;  /* Fall thru into Read/Write */
      case 'i':   g.okRead = g.okWrite = 1;                     break;
      case 'o':   g.okRead = 1;                                 break;
      case 'z':   g.okZip = 1;                                  break;

      case 'd':   g.okDelete = 1;                               break;
      case 'h':   g.okHistory = 1;                              break;
      case 'g':   g.okClone = 1;                                break;
Changes to src/setup.c.
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643

  style_header("Access Control Settings");
  db_begin_transaction();
  @ <form action="%s(g.zBaseURL)/setup_access" method="POST">
  login_insert_csrf_secret();
  @ <hr>
  onoff_attribute("Require password for local access",
     "localauth", "localauth", 1);
  @ <p>When enabled, the password sign-in is required for
  @ web access coming from 127.0.0.1.  When disabled, web access
  @ from 127.0.0.1 is allows without any login - the user id is selected
  @ from the ~/.fossil database. Password login is always required
  @ for incoming web connections on internet addresses other than
  @ 127.0.0.1.</p></li>

  @ <hr>
  onoff_attribute("Inherit capabilities from anonymous user",
     "inherit-anon", "inherit-anon", 0);
  @ <p>When enabled, all web users inherit capabilities from
  @ "anonymous", as well as from "nobody".</p></li>

  @ <hr>
  entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
  @ <p>The number of hours for which a login is valid.  This must be a
  @ positive number.  The default is 8760 hours which is approximately equal
  @ to a year.</p>

  @ <hr>







|







<
<
<
<
<
<







616
617
618
619
620
621
622
623
624
625
626
627
628
629
630






631
632
633
634
635
636
637

  style_header("Access Control Settings");
  db_begin_transaction();
  @ <form action="%s(g.zBaseURL)/setup_access" method="POST">
  login_insert_csrf_secret();
  @ <hr>
  onoff_attribute("Require password for local access",
     "localauth", "localauth", 0);
  @ <p>When enabled, the password sign-in is required for
  @ web access coming from 127.0.0.1.  When disabled, web access
  @ from 127.0.0.1 is allows without any login - the user id is selected
  @ from the ~/.fossil database. Password login is always required
  @ for incoming web connections on internet addresses other than
  @ 127.0.0.1.</p></li>







  @ <hr>
  entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
  @ <p>The number of hours for which a login is valid.  This must be a
  @ positive number.  The default is 8760 hours which is approximately equal
  @ to a year.</p>

  @ <hr>
Changes to src/xfer.c.
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743




744
745
746
747
748
749
750
      if( !g.okAdmin ){
        cgi_reset_content();
        @ error not\sauthorized\sto\spush\sconfiguration
        nErr++;
        break;
      }
      if( zName[0]!='@' ){
        if( !recvConfig ){
          configure_prepare_to_receive(0);
          recvConfig = 1;
        }
        db_multi_exec(
            "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
            zName, blob_str(&content)
        );
      }else{
        /* Notice that we are evaluating arbitrary SQL received from the
        ** client.  But this can only happen if the client has authenticated
        ** as an administrator, so presumably we trust the client at this
        ** point.
        */




        db_multi_exec("%s", blob_str(&content));
      }
      blob_reset(&content);
      blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
    }else

      







<
<
<
<










>
>
>
>







723
724
725
726
727
728
729




730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
      if( !g.okAdmin ){
        cgi_reset_content();
        @ error not\sauthorized\sto\spush\sconfiguration
        nErr++;
        break;
      }
      if( zName[0]!='@' ){




        db_multi_exec(
            "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
            zName, blob_str(&content)
        );
      }else{
        /* Notice that we are evaluating arbitrary SQL received from the
        ** client.  But this can only happen if the client has authenticated
        ** as an administrator, so presumably we trust the client at this
        ** point.
        */
        if( !recvConfig ){
          configure_prepare_to_receive(0);
          recvConfig = 1;
        }
        db_multi_exec("%s", blob_str(&content));
      }
      blob_reset(&content);
      blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
    }else