Fossil

Check-in [9b4e157b]
Login

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

Overview
Comment:Merge the fix to the login-by-email-address patch.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9b4e157b1e1e51247b285e6773fe510de12f71b3e58d26491262a557ce5a9299
User & Date: drh 2018-08-12 10:42:50.128
Context
2018-08-12
21:35
Add /forum link to sitemap if user has RdForum capability ... (check-in: 5ad7222f user: wyoung tags: trunk)
10:42
Merge the fix to the login-by-email-address patch. ... (check-in: 9b4e157b user: drh tags: trunk)
06:11
URL fix in forum.wiki ... (check-in: 542c5576 user: wyoung tags: trunk)
2018-08-11
23:51
Coding style tweak. ... (Closed-Leaf check-in: 52b9caa5 user: mistachkin tags: login-with-email)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/json_login.c.
122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+









-
+







    }
  }

#if 0
  {
    /* only for debugging the PD()-incorrect-result problem */
    cson_object * o = NULL;
    uid = login_search_uid( name, pw );
    uid = login_search_uid( &name, pw );
    payload = cson_value_new_object();
    o = cson_value_get_object(payload);
    cson_object_set( o, "n", cson_value_new_string(name,strlen(name)));
    cson_object_set( o, "p", cson_value_new_string(pw,strlen(pw)));
    return payload;
  }
#endif
  uid = anonSeed
    ? login_is_valid_anonymous(name, pw, anonSeed)
    : login_search_uid(name, pw)
    : login_search_uid(&name, pw)
    ;
  if( !uid ){
    g.json.resultCode = preciseErrors
      ? FSL_JSON_E_LOGIN_FAILED_NOTFOUND
      : FSL_JSON_E_LOGIN_FAILED;
    return NULL;
  }else{
Changes to src/login.c.
204
205
206
207
208
209
210








211
212
213
214
215


216
217
218
219
220
221
222
223
224

225
226
227
228

229
230
231
232

233
234
235
236
237
238

239
240
241






242
243
244
245
246
247
248
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221


222
223
224
225
226
227
228
229
230
231

232
233
234
235

236
237
238
239

240
241
242
243
244
245

246
247


248
249
250
251
252
253
254
255
256
257
258
259
260







+
+
+
+
+
+
+
+



-
-
+
+








-
+



-
+



-
+





-
+

-
-
+
+
+
+
+
+







}

/*
** Searches for the user ID matching the given name and password.
** On success it returns a positive value. On error it returns 0.
** On serious (DB-level) error it will probably exit.
**
** zUsername uses double indirection because we may re-point *zUsername
** at a C string allocated with fossil_strdup() if you pass an email
** address instead and we find that address in the user table's info
** field, which is expected to contain a string of the form "Human Name
** <human@example.com>".  In that case, *zUsername will point to that
** user's actual login name on return, causing a leak unless the caller
** is diligent enough to check whether its pointer was re-pointed.
**
** zPassword may be either the plain-text form or the encrypted
** form of the user's password.
*/
int login_search_uid(const char *zUsername, const char *zPasswd){
  char *zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0);
int login_search_uid(const char **pzUsername, const char *zPasswd){
  char *zSha1Pw = sha1_shared_secret(zPasswd, *pzUsername, 0);
  int uid = db_int(0,
    "SELECT uid FROM user"
    " WHERE login=%Q"
    "   AND length(cap)>0 AND length(pw)>0"
    "   AND login NOT IN ('anonymous','nobody','developer','reader')"
    "   AND (pw=%Q OR (length(pw)<>40 AND pw=%Q))"
    "   AND (info NOT LIKE '%%expires 20%%'"
    "      OR substr(info,instr(lower(info),'expires')+8,10)>datetime('now'))",
    zUsername, zSha1Pw, zPasswd
    *pzUsername, zSha1Pw, zPasswd
  );

  /* If we did not find a login on the first attempt, and the username
  ** looks like an email address, the perhaps the user entired their
  ** looks like an email address, then perhaps the user entered their
  ** email address instead of their login.  Try again to match the user
  ** against email addresses contained in the "info" field.
  */
  if( uid==0 && strchr(zUsername,'@')!=0 ){
  if( uid==0 && strchr(*pzUsername,'@')!=0 ){
    Stmt q;
    db_prepare(&q,
      "SELECT login FROM user"
      " WHERE find_emailaddr(info)=%Q"
      "   AND instr(login,'@')==0",
      zUsername
      *pzUsername
    );
    while( uid==0 && db_step(&q)==SQLITE_ROW ){
       uid = login_search_uid(db_column_text(&q,0),zPasswd);
    while( db_step(&q)==SQLITE_ROW ){
      const char *zLogin = db_column_text(&q,0);
      if( (uid = login_search_uid(&zLogin, zPasswd) ) != 0 ){
        *pzUsername = fossil_strdup(zLogin);
        break;
      }
    }
    db_finalize(&q);
  }    
  free(zSha1Pw);
  return uid;
}

648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
660
661
662
663
664
665
666

667
668
669
670
671
672
673
674







-
+







    login_set_anon_cookie(zIpAddr, NULL);
    record_login_attempt("anonymous", zIpAddr, 1);
    redirect_to_g();
  }
  if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){
    /* Attempting to log in as a user other than anonymous.
    */
    uid = login_search_uid(zUsername, zPasswd);
    uid = login_search_uid(&zUsername, zPasswd);
    if( uid<=0 ){
      sleep(1);
      zErrMsg =
         @ <p><span class="loginError">
         @ You entered an unknown user or an incorrect password.
         @ </span></p>
      ;
949
950
951
952
953
954
955
956

957
958
959
960
961
962
963
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975







-
+







    zDecode[i] = 0;
    zUsername = zDecode;
    zPasswd = &zDecode[i+1];

    /* Attempting to log in as the user provided by HTTP
    ** basic auth
    */
    uid = login_search_uid(zUsername, zPasswd);
    uid = login_search_uid(&zUsername, zPasswd);
    if( uid>0 ){
      record_login_attempt(zUsername, zIpAddr, 1);
    }else{
      record_login_attempt(zUsername, zIpAddr, 0);

      /* The user attempted to login specifically with HTTP basic
      ** auth, but provided invalid credentials. Inform them of
Changes to src/smtp.c.
1351
1352
1353
1354
1355
1356
1357
1358
1359


1360
1361
1362

1363
1364
1365

1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1351
1352
1353
1354
1355
1356
1357


1358
1359

1360

1361



1362









1363
1364
1365
1366
1367
1368
1369







-
-
+
+
-

-
+
-
-
-
+
-
-
-
-
-
-
-
-
-







  fflush(stdout);
  if( pLog ) fprintf(pLog, "S: %s\n", zLine);
}

/*
** Try to log in for zUser and zPass.
**
** If zUser/zPass does not work as written, then modify zUser by
** omitting everything after the "@" (if there is one) and trying
** zUser can either point to a Fossil user name or to an email address
** found in the user table's info field, in angle brackets.
** again.
*/
static int pop3_login(char *zUser, char *zPass){
static int pop3_login(const char *zUser, char *zPass){
  int uid;
  int i;
  uid = login_search_uid(zUser, zPass);
  return login_search_uid(&zUser, zPass) != 0;
  if( uid ) return 1;
  for(i=0; zUser[i] && zUser[i]!='@'; i++){}
  if( zUser[i]=='@' ){
    zUser[i] = 0;
    uid = login_search_uid(zUser, zPass);
    if( uid ) return 1;
    zUser[i] = '@';
  }
  return 0; 
}

/*
** COMMAND: pop3d
**
** Usage: %fossil pop3d [OPTIONS] REPOSITORY
**