Fossil SCM
Optionally record successful and failed login attempts in the ACCESSLOG table. This defaults to off.
Commit
6fdf52980316e49823efd9bdebf463f6118ee192
Parent
ffe1b60a36be252…
2 files changed
+1
+28
-2
M
src/db.c
+1
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -1595,10 +1595,11 @@ | ||
| 1595 | 1595 | int width; /* Width of display. 0 for boolean values */ |
| 1596 | 1596 | char const *def; /* Default value */ |
| 1597 | 1597 | }; |
| 1598 | 1598 | #endif /* INTERFACE */ |
| 1599 | 1599 | struct stControlSettings const ctrlSettings[] = { |
| 1600 | + { "access-log", 0, 0, "off" }, | |
| 1600 | 1601 | { "auto-captcha", "autocaptcha", 0, "on" }, |
| 1601 | 1602 | { "auto-shun", 0, 0, "on" }, |
| 1602 | 1603 | { "autosync", 0, 0, "on" }, |
| 1603 | 1604 | { "binary-glob", 0, 32, "" }, |
| 1604 | 1605 | { "clearsign", 0, 0, "off" }, |
| 1605 | 1606 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1595,10 +1595,11 @@ | |
| 1595 | int width; /* Width of display. 0 for boolean values */ |
| 1596 | char const *def; /* Default value */ |
| 1597 | }; |
| 1598 | #endif /* INTERFACE */ |
| 1599 | struct stControlSettings const ctrlSettings[] = { |
| 1600 | { "auto-captcha", "autocaptcha", 0, "on" }, |
| 1601 | { "auto-shun", 0, 0, "on" }, |
| 1602 | { "autosync", 0, 0, "on" }, |
| 1603 | { "binary-glob", 0, 32, "" }, |
| 1604 | { "clearsign", 0, 0, "off" }, |
| 1605 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -1595,10 +1595,11 @@ | |
| 1595 | int width; /* Width of display. 0 for boolean values */ |
| 1596 | char const *def; /* Default value */ |
| 1597 | }; |
| 1598 | #endif /* INTERFACE */ |
| 1599 | struct stControlSettings const ctrlSettings[] = { |
| 1600 | { "access-log", 0, 0, "off" }, |
| 1601 | { "auto-captcha", "autocaptcha", 0, "on" }, |
| 1602 | { "auto-shun", 0, 0, "on" }, |
| 1603 | { "autosync", 0, 0, "on" }, |
| 1604 | { "binary-glob", 0, 32, "" }, |
| 1605 | { "clearsign", 0, 0, "off" }, |
| 1606 |
+28
-2
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -114,10 +114,32 @@ | ||
| 114 | 114 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 115 | 115 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| 116 | 116 | " AND length(pw)>0 AND length(cap)>0"); |
| 117 | 117 | return uid; |
| 118 | 118 | } |
| 119 | + | |
| 120 | +/* | |
| 121 | +** Make a record of a login attempt, if login record keeping is enabled. | |
| 122 | +*/ | |
| 123 | +static void record_login_attempt( | |
| 124 | + const char *zUsername, /* Name of user logging in */ | |
| 125 | + const char *zIpAddr, /* IP address from which they logged in */ | |
| 126 | + int bSuccess /* True if the attempt was a success */ | |
| 127 | +){ | |
| 128 | + if( !db_get_boolean("access-log", 0) ) return; | |
| 129 | + db_multi_exec( | |
| 130 | + "CREATE TABLE IF NOT EXISTS %s.accesslog(" | |
| 131 | + " uname TEXT," | |
| 132 | + " ipaddr TEXT," | |
| 133 | + " success BOOLEAN," | |
| 134 | + " mtime TIMESTAMP" | |
| 135 | + ");" | |
| 136 | + "INSERT INTO accesslog(uname,ipaddr,success,mtime)" | |
| 137 | + "VALUES(%Q,%Q,%d,julianday('now'));", | |
| 138 | + db_name("repository"), zUsername, zIpAddr, bSuccess | |
| 139 | + ); | |
| 140 | +} | |
| 119 | 141 | |
| 120 | 142 | /* |
| 121 | 143 | ** WEBPAGE: login |
| 122 | 144 | ** WEBPAGE: logout |
| 123 | 145 | ** WEBPAGE: my |
| @@ -135,10 +157,11 @@ | ||
| 135 | 157 | const char *zAnonPw = 0; |
| 136 | 158 | int anonFlag; |
| 137 | 159 | char *zErrMsg = ""; |
| 138 | 160 | int uid; /* User id loged in user */ |
| 139 | 161 | char *zSha1Pw; |
| 162 | + const char *zIpAddr; /* IP address of requestor */ | |
| 140 | 163 | |
| 141 | 164 | login_check_credentials(); |
| 142 | 165 | zUsername = P("u"); |
| 143 | 166 | zPasswd = P("p"); |
| 144 | 167 | anonFlag = P("anon")!=0; |
| @@ -173,28 +196,28 @@ | ||
| 173 | 196 | ); |
| 174 | 197 | redirect_to_g(); |
| 175 | 198 | return; |
| 176 | 199 | } |
| 177 | 200 | } |
| 201 | + zIpAddr = PD("REMOTE_ADDR","nil"); | |
| 178 | 202 | uid = isValidAnonymousLogin(zUsername, zPasswd); |
| 179 | 203 | if( uid>0 ){ |
| 180 | 204 | char *zNow; /* Current time (julian day number) */ |
| 181 | - const char *zIpAddr; /* IP address of requestor */ | |
| 182 | 205 | char *zCookie; /* The login cookie */ |
| 183 | 206 | const char *zCookieName; /* Name of the login cookie */ |
| 184 | 207 | Blob b; /* Blob used during cookie construction */ |
| 185 | 208 | |
| 186 | - zIpAddr = PD("REMOTE_ADDR","nil"); | |
| 187 | 209 | zCookieName = login_cookie_name(); |
| 188 | 210 | zNow = db_text("0", "SELECT julianday('now')"); |
| 189 | 211 | blob_init(&b, zNow, -1); |
| 190 | 212 | blob_appendf(&b, "/%z/%s", ipPrefix(zIpAddr), db_get("captcha-secret","")); |
| 191 | 213 | sha1sum_blob(&b, &b); |
| 192 | 214 | zCookie = sqlite3_mprintf("anon/%s/%s", zNow, blob_buffer(&b)); |
| 193 | 215 | blob_reset(&b); |
| 194 | 216 | free(zNow); |
| 195 | 217 | cgi_set_cookie(zCookieName, zCookie, 0, 6*3600); |
| 218 | + record_login_attempt("anonyous", zIpAddr, 1); | |
| 196 | 219 | redirect_to_g(); |
| 197 | 220 | } |
| 198 | 221 | if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ |
| 199 | 222 | zSha1Pw = sha1_shared_secret(zPasswd, zUsername); |
| 200 | 223 | uid = db_int(0, |
| @@ -209,19 +232,21 @@ | ||
| 209 | 232 | zErrMsg = |
| 210 | 233 | @ <p><span class="loginError"> |
| 211 | 234 | @ You entered an unknown user or an incorrect password. |
| 212 | 235 | @ </span></p> |
| 213 | 236 | ; |
| 237 | + record_login_attempt(zUsername, zIpAddr, 0); | |
| 214 | 238 | }else{ |
| 215 | 239 | char *zCookie; |
| 216 | 240 | const char *zCookieName = login_cookie_name(); |
| 217 | 241 | const char *zExpire = db_get("cookie-expire","8766"); |
| 218 | 242 | int expires = atoi(zExpire)*3600; |
| 219 | 243 | const char *zIpAddr = PD("REMOTE_ADDR","nil"); |
| 220 | 244 | |
| 221 | 245 | zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); |
| 222 | 246 | cgi_set_cookie(zCookieName, zCookie, 0, expires); |
| 247 | + record_login_attempt(zUsername, zIpAddr, 1); | |
| 223 | 248 | db_multi_exec( |
| 224 | 249 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 225 | 250 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 226 | 251 | zCookie, zIpAddr, expires, uid |
| 227 | 252 | ); |
| @@ -714,10 +739,11 @@ | ||
| 714 | 739 | expires = atoi(zExpire)*3600; |
| 715 | 740 | zIpAddr = PD("REMOTE_ADDR","nil"); |
| 716 | 741 | |
| 717 | 742 | zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); |
| 718 | 743 | cgi_set_cookie(zCookieName, zCookie, 0, expires); |
| 744 | + record_login_attempt(zUsername, zIpAddr, 1); | |
| 719 | 745 | db_multi_exec( |
| 720 | 746 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 721 | 747 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 722 | 748 | zCookie, zIpAddr, expires, uid |
| 723 | 749 | ); |
| 724 | 750 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -114,10 +114,32 @@ | |
| 114 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 115 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| 116 | " AND length(pw)>0 AND length(cap)>0"); |
| 117 | return uid; |
| 118 | } |
| 119 | |
| 120 | /* |
| 121 | ** WEBPAGE: login |
| 122 | ** WEBPAGE: logout |
| 123 | ** WEBPAGE: my |
| @@ -135,10 +157,11 @@ | |
| 135 | const char *zAnonPw = 0; |
| 136 | int anonFlag; |
| 137 | char *zErrMsg = ""; |
| 138 | int uid; /* User id loged in user */ |
| 139 | char *zSha1Pw; |
| 140 | |
| 141 | login_check_credentials(); |
| 142 | zUsername = P("u"); |
| 143 | zPasswd = P("p"); |
| 144 | anonFlag = P("anon")!=0; |
| @@ -173,28 +196,28 @@ | |
| 173 | ); |
| 174 | redirect_to_g(); |
| 175 | return; |
| 176 | } |
| 177 | } |
| 178 | uid = isValidAnonymousLogin(zUsername, zPasswd); |
| 179 | if( uid>0 ){ |
| 180 | char *zNow; /* Current time (julian day number) */ |
| 181 | const char *zIpAddr; /* IP address of requestor */ |
| 182 | char *zCookie; /* The login cookie */ |
| 183 | const char *zCookieName; /* Name of the login cookie */ |
| 184 | Blob b; /* Blob used during cookie construction */ |
| 185 | |
| 186 | zIpAddr = PD("REMOTE_ADDR","nil"); |
| 187 | zCookieName = login_cookie_name(); |
| 188 | zNow = db_text("0", "SELECT julianday('now')"); |
| 189 | blob_init(&b, zNow, -1); |
| 190 | blob_appendf(&b, "/%z/%s", ipPrefix(zIpAddr), db_get("captcha-secret","")); |
| 191 | sha1sum_blob(&b, &b); |
| 192 | zCookie = sqlite3_mprintf("anon/%s/%s", zNow, blob_buffer(&b)); |
| 193 | blob_reset(&b); |
| 194 | free(zNow); |
| 195 | cgi_set_cookie(zCookieName, zCookie, 0, 6*3600); |
| 196 | redirect_to_g(); |
| 197 | } |
| 198 | if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ |
| 199 | zSha1Pw = sha1_shared_secret(zPasswd, zUsername); |
| 200 | uid = db_int(0, |
| @@ -209,19 +232,21 @@ | |
| 209 | zErrMsg = |
| 210 | @ <p><span class="loginError"> |
| 211 | @ You entered an unknown user or an incorrect password. |
| 212 | @ </span></p> |
| 213 | ; |
| 214 | }else{ |
| 215 | char *zCookie; |
| 216 | const char *zCookieName = login_cookie_name(); |
| 217 | const char *zExpire = db_get("cookie-expire","8766"); |
| 218 | int expires = atoi(zExpire)*3600; |
| 219 | const char *zIpAddr = PD("REMOTE_ADDR","nil"); |
| 220 | |
| 221 | zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); |
| 222 | cgi_set_cookie(zCookieName, zCookie, 0, expires); |
| 223 | db_multi_exec( |
| 224 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 225 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 226 | zCookie, zIpAddr, expires, uid |
| 227 | ); |
| @@ -714,10 +739,11 @@ | |
| 714 | expires = atoi(zExpire)*3600; |
| 715 | zIpAddr = PD("REMOTE_ADDR","nil"); |
| 716 | |
| 717 | zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); |
| 718 | cgi_set_cookie(zCookieName, zCookie, 0, expires); |
| 719 | db_multi_exec( |
| 720 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 721 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 722 | zCookie, zIpAddr, expires, uid |
| 723 | ); |
| 724 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -114,10 +114,32 @@ | |
| 114 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 115 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| 116 | " AND length(pw)>0 AND length(cap)>0"); |
| 117 | return uid; |
| 118 | } |
| 119 | |
| 120 | /* |
| 121 | ** Make a record of a login attempt, if login record keeping is enabled. |
| 122 | */ |
| 123 | static void record_login_attempt( |
| 124 | const char *zUsername, /* Name of user logging in */ |
| 125 | const char *zIpAddr, /* IP address from which they logged in */ |
| 126 | int bSuccess /* True if the attempt was a success */ |
| 127 | ){ |
| 128 | if( !db_get_boolean("access-log", 0) ) return; |
| 129 | db_multi_exec( |
| 130 | "CREATE TABLE IF NOT EXISTS %s.accesslog(" |
| 131 | " uname TEXT," |
| 132 | " ipaddr TEXT," |
| 133 | " success BOOLEAN," |
| 134 | " mtime TIMESTAMP" |
| 135 | ");" |
| 136 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 137 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 138 | db_name("repository"), zUsername, zIpAddr, bSuccess |
| 139 | ); |
| 140 | } |
| 141 | |
| 142 | /* |
| 143 | ** WEBPAGE: login |
| 144 | ** WEBPAGE: logout |
| 145 | ** WEBPAGE: my |
| @@ -135,10 +157,11 @@ | |
| 157 | const char *zAnonPw = 0; |
| 158 | int anonFlag; |
| 159 | char *zErrMsg = ""; |
| 160 | int uid; /* User id loged in user */ |
| 161 | char *zSha1Pw; |
| 162 | const char *zIpAddr; /* IP address of requestor */ |
| 163 | |
| 164 | login_check_credentials(); |
| 165 | zUsername = P("u"); |
| 166 | zPasswd = P("p"); |
| 167 | anonFlag = P("anon")!=0; |
| @@ -173,28 +196,28 @@ | |
| 196 | ); |
| 197 | redirect_to_g(); |
| 198 | return; |
| 199 | } |
| 200 | } |
| 201 | zIpAddr = PD("REMOTE_ADDR","nil"); |
| 202 | uid = isValidAnonymousLogin(zUsername, zPasswd); |
| 203 | if( uid>0 ){ |
| 204 | char *zNow; /* Current time (julian day number) */ |
| 205 | char *zCookie; /* The login cookie */ |
| 206 | const char *zCookieName; /* Name of the login cookie */ |
| 207 | Blob b; /* Blob used during cookie construction */ |
| 208 | |
| 209 | zCookieName = login_cookie_name(); |
| 210 | zNow = db_text("0", "SELECT julianday('now')"); |
| 211 | blob_init(&b, zNow, -1); |
| 212 | blob_appendf(&b, "/%z/%s", ipPrefix(zIpAddr), db_get("captcha-secret","")); |
| 213 | sha1sum_blob(&b, &b); |
| 214 | zCookie = sqlite3_mprintf("anon/%s/%s", zNow, blob_buffer(&b)); |
| 215 | blob_reset(&b); |
| 216 | free(zNow); |
| 217 | cgi_set_cookie(zCookieName, zCookie, 0, 6*3600); |
| 218 | record_login_attempt("anonyous", zIpAddr, 1); |
| 219 | redirect_to_g(); |
| 220 | } |
| 221 | if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ |
| 222 | zSha1Pw = sha1_shared_secret(zPasswd, zUsername); |
| 223 | uid = db_int(0, |
| @@ -209,19 +232,21 @@ | |
| 232 | zErrMsg = |
| 233 | @ <p><span class="loginError"> |
| 234 | @ You entered an unknown user or an incorrect password. |
| 235 | @ </span></p> |
| 236 | ; |
| 237 | record_login_attempt(zUsername, zIpAddr, 0); |
| 238 | }else{ |
| 239 | char *zCookie; |
| 240 | const char *zCookieName = login_cookie_name(); |
| 241 | const char *zExpire = db_get("cookie-expire","8766"); |
| 242 | int expires = atoi(zExpire)*3600; |
| 243 | const char *zIpAddr = PD("REMOTE_ADDR","nil"); |
| 244 | |
| 245 | zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); |
| 246 | cgi_set_cookie(zCookieName, zCookie, 0, expires); |
| 247 | record_login_attempt(zUsername, zIpAddr, 1); |
| 248 | db_multi_exec( |
| 249 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 250 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 251 | zCookie, zIpAddr, expires, uid |
| 252 | ); |
| @@ -714,10 +739,11 @@ | |
| 739 | expires = atoi(zExpire)*3600; |
| 740 | zIpAddr = PD("REMOTE_ADDR","nil"); |
| 741 | |
| 742 | zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid); |
| 743 | cgi_set_cookie(zCookieName, zCookie, 0, expires); |
| 744 | record_login_attempt(zUsername, zIpAddr, 1); |
| 745 | db_multi_exec( |
| 746 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 747 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 748 | zCookie, zIpAddr, expires, uid |
| 749 | ); |
| 750 |