Fossil

Check-in [6fdf5298]
Login

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

Overview
Comment:Optionally record successful and failed login attempts in the ACCESSLOG table. This defaults to off.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6fdf52980316e49823efd9bdebf463f6118ee192
User & Date: drh 2011-01-19 02:35:03
Context
2011-01-19
02:57
Add a primitive display of the access-log history. check-in: f274222e user: drh tags: trunk
02:35
Optionally record successful and failed login attempts in the ACCESSLOG table. This defaults to off. check-in: 6fdf5298 user: drh tags: trunk
2011-01-18
20:47
Preserve timestamps across an "update" to reduce I/O on the next "status". Ticket [809a9612055340d06]. check-in: ffe1b60a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/db.c.

1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
  char const *name;     /* Name of the setting */
  char const *var;      /* Internal variable name used by db_set() */
  int width;            /* Width of display.  0 for boolean values */
  char const *def;      /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {

  { "auto-captcha",  "autocaptcha",    0, "on"                  },
  { "auto-shun",     0,                0, "on"                  },
  { "autosync",      0,                0, "on"                  },
  { "binary-glob",   0,               32, ""                    },
  { "clearsign",     0,                0, "off"                 },
  { "default-perms", 0,               16, "u"                   },
  { "diff-command",  0,               16, ""                    },







>







1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
  char const *name;     /* Name of the setting */
  char const *var;      /* Internal variable name used by db_set() */
  int width;            /* Width of display.  0 for boolean values */
  char const *def;      /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
  { "access-log",    0,                0, "off"                 },
  { "auto-captcha",  "autocaptcha",    0, "on"                  },
  { "auto-shun",     0,                0, "on"                  },
  { "autosync",      0,                0, "on"                  },
  { "binary-glob",   0,               32, ""                    },
  { "clearsign",     0,                0, "off"                 },
  { "default-perms", 0,               16, "u"                   },
  { "diff-command",  0,               16, ""                    },

Changes to src/login.c.

112
113
114
115
116
117
118






















119
120
121
122
123
124
125
...
133
134
135
136
137
138
139

140
141
142
143
144
145
146
...
171
172
173
174
175
176
177

178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
...
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
...
712
713
714
715
716
717
718

719
720
721
722
723
724
725
  if( zCS==0 ) return 0;
  zPw = captcha_decode((unsigned int)atoi(zCS));
  if( fossil_stricmp(zPw, zPassword)!=0 ) return 0;
  uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'"
                  " AND length(pw)>0 AND length(cap)>0");
  return uid;
}























/*
** WEBPAGE: login
** WEBPAGE: logout
** WEBPAGE: my
**
** Generate the login page.
................................................................................
  const char *zUsername, *zPasswd;
  const char *zNew1, *zNew2;
  const char *zAnonPw = 0;
  int anonFlag;
  char *zErrMsg = "";
  int uid;                     /* User id loged in user */
  char *zSha1Pw;


  login_check_credentials();
  zUsername = P("u");
  zPasswd = P("p");
  anonFlag = P("anon")!=0;
  if( P("out")!=0 ){
    const char *zCookieName = login_cookie_name();
................................................................................
      db_multi_exec(
         "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
      );
      redirect_to_g();
      return;
    }
  }

  uid = isValidAnonymousLogin(zUsername, zPasswd);
  if( uid>0 ){
    char *zNow;                  /* Current time (julian day number) */
    const char *zIpAddr;         /* IP address of requestor */
    char *zCookie;               /* The login cookie */
    const char *zCookieName;     /* Name of the login cookie */
    Blob b;                      /* Blob used during cookie construction */

    zIpAddr = PD("REMOTE_ADDR","nil");
    zCookieName = login_cookie_name();
    zNow = db_text("0", "SELECT julianday('now')");
    blob_init(&b, zNow, -1);
    blob_appendf(&b, "/%z/%s", ipPrefix(zIpAddr), db_get("captcha-secret",""));
    sha1sum_blob(&b, &b);
    zCookie = sqlite3_mprintf("anon/%s/%s", zNow, blob_buffer(&b));
    blob_reset(&b);
    free(zNow);
    cgi_set_cookie(zCookieName, zCookie, 0, 6*3600);

    redirect_to_g();
  }
  if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){
    zSha1Pw = sha1_shared_secret(zPasswd, zUsername);
    uid = db_int(0,
        "SELECT uid FROM user"
        " WHERE login=%Q"
................................................................................
    if( uid<=0 ){
      sleep(1);
      zErrMsg = 
         @ <p><span class="loginError">
         @ You entered an unknown user or an incorrect password.
         @ </span></p>
      ;

    }else{
      char *zCookie;
      const char *zCookieName = login_cookie_name();
      const char *zExpire = db_get("cookie-expire","8766");
      int expires = atoi(zExpire)*3600;
      const char *zIpAddr = PD("REMOTE_ADDR","nil");
 
      zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
      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();
    }
................................................................................
        zCookieName = login_cookie_name();
        zExpire = db_get("cookie-expire","8766");
        expires = atoi(zExpire)*3600;
        zIpAddr = PD("REMOTE_ADDR","nil");

        zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
        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();








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







 







>







 







>



<




<









>







 







>









>







 







>







112
113
114
115
116
117
118
119
120
121
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
147
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
...
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
...
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
  if( zCS==0 ) return 0;
  zPw = captcha_decode((unsigned int)atoi(zCS));
  if( fossil_stricmp(zPw, zPassword)!=0 ) return 0;
  uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'"
                  " AND length(pw)>0 AND length(cap)>0");
  return uid;
}

/*
** Make a record of a login attempt, if login record keeping is enabled.
*/
static void record_login_attempt(
  const char *zUsername,     /* Name of user logging in */
  const char *zIpAddr,       /* IP address from which they logged in */
  int bSuccess               /* True if the attempt was a success */
){
  if( !db_get_boolean("access-log", 0) ) return;
  db_multi_exec(
    "CREATE TABLE IF NOT EXISTS %s.accesslog("
    "  uname TEXT,"
    "  ipaddr TEXT,"
    "  success BOOLEAN,"
    "  mtime TIMESTAMP"
    ");"
    "INSERT INTO accesslog(uname,ipaddr,success,mtime)"
    "VALUES(%Q,%Q,%d,julianday('now'));",
    db_name("repository"), zUsername, zIpAddr, bSuccess
  );
}

/*
** WEBPAGE: login
** WEBPAGE: logout
** WEBPAGE: my
**
** Generate the login page.
................................................................................
  const char *zUsername, *zPasswd;
  const char *zNew1, *zNew2;
  const char *zAnonPw = 0;
  int anonFlag;
  char *zErrMsg = "";
  int uid;                     /* User id loged in user */
  char *zSha1Pw;
  const char *zIpAddr;         /* IP address of requestor */

  login_check_credentials();
  zUsername = P("u");
  zPasswd = P("p");
  anonFlag = P("anon")!=0;
  if( P("out")!=0 ){
    const char *zCookieName = login_cookie_name();
................................................................................
      db_multi_exec(
         "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
      );
      redirect_to_g();
      return;
    }
  }
  zIpAddr = PD("REMOTE_ADDR","nil");
  uid = isValidAnonymousLogin(zUsername, zPasswd);
  if( uid>0 ){
    char *zNow;                  /* Current time (julian day number) */

    char *zCookie;               /* The login cookie */
    const char *zCookieName;     /* Name of the login cookie */
    Blob b;                      /* Blob used during cookie construction */


    zCookieName = login_cookie_name();
    zNow = db_text("0", "SELECT julianday('now')");
    blob_init(&b, zNow, -1);
    blob_appendf(&b, "/%z/%s", ipPrefix(zIpAddr), db_get("captcha-secret",""));
    sha1sum_blob(&b, &b);
    zCookie = sqlite3_mprintf("anon/%s/%s", zNow, blob_buffer(&b));
    blob_reset(&b);
    free(zNow);
    cgi_set_cookie(zCookieName, zCookie, 0, 6*3600);
    record_login_attempt("anonyous", zIpAddr, 1);
    redirect_to_g();
  }
  if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){
    zSha1Pw = sha1_shared_secret(zPasswd, zUsername);
    uid = db_int(0,
        "SELECT uid FROM user"
        " WHERE login=%Q"
................................................................................
    if( uid<=0 ){
      sleep(1);
      zErrMsg = 
         @ <p><span class="loginError">
         @ You entered an unknown user or an incorrect password.
         @ </span></p>
      ;
      record_login_attempt(zUsername, zIpAddr, 0);
    }else{
      char *zCookie;
      const char *zCookieName = login_cookie_name();
      const char *zExpire = db_get("cookie-expire","8766");
      int expires = atoi(zExpire)*3600;
      const char *zIpAddr = PD("REMOTE_ADDR","nil");
 
      zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
      cgi_set_cookie(zCookieName, zCookie, 0, expires);
      record_login_attempt(zUsername, zIpAddr, 1);
      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();
    }
................................................................................
        zCookieName = login_cookie_name();
        zExpire = db_get("cookie-expire","8766");
        expires = atoi(zExpire)*3600;
        zIpAddr = PD("REMOTE_ADDR","nil");

        zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
        cgi_set_cookie(zCookieName, zCookie, 0, expires);
        record_login_attempt(zUsername, zIpAddr, 1);
        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();