Fossil SCM
Bug fix: Make sure the constant_time_cmp() SQL function is registered when rendering the login page.
Commit
2f4a101ca511606a571350fe55be2e0b4267297c
Parent
8b3c6ebb375615f…
1 file changed
+32
-28
+32
-28
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -192,10 +192,37 @@ | ||
| 192 | 192 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 193 | 193 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 194 | 194 | zUsername, zIpAddr, bSuccess |
| 195 | 195 | ); |
| 196 | 196 | } |
| 197 | + | |
| 198 | +/* | |
| 199 | +** SQL function for constant time comparison of two values. | |
| 200 | +** Sets result to 0 if two values are equal. | |
| 201 | +*/ | |
| 202 | +static void constant_time_cmp_function( | |
| 203 | + sqlite3_context *context, | |
| 204 | + int argc, | |
| 205 | + sqlite3_value **argv | |
| 206 | +){ | |
| 207 | + const unsigned char *buf1, *buf2; | |
| 208 | + int len, i; | |
| 209 | + unsigned char rc = 0; | |
| 210 | + | |
| 211 | + assert( argc==2 ); | |
| 212 | + len = sqlite3_value_bytes(argv[0]); | |
| 213 | + if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){ | |
| 214 | + rc = 1; | |
| 215 | + }else{ | |
| 216 | + buf1 = sqlite3_value_text(argv[0]); | |
| 217 | + buf2 = sqlite3_value_text(argv[1]); | |
| 218 | + for( i=0; i<len; i++ ){ | |
| 219 | + rc = rc | (buf1[i] ^ buf2[i]); | |
| 220 | + } | |
| 221 | + } | |
| 222 | + sqlite3_result_int(context, rc); | |
| 223 | +} | |
| 197 | 224 | |
| 198 | 225 | /* |
| 199 | 226 | ** WEBPAGE: login |
| 200 | 227 | ** WEBPAGE: logout |
| 201 | 228 | ** WEBPAGE: my |
| @@ -217,20 +244,24 @@ | ||
| 217 | 244 | char *zSha1Pw; |
| 218 | 245 | const char *zIpAddr; /* IP address of requestor */ |
| 219 | 246 | char *zRemoteAddr; /* Abbreviated IP address of requestor */ |
| 220 | 247 | |
| 221 | 248 | login_check_credentials(); |
| 249 | + sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, | |
| 250 | + constant_time_cmp_function, 0, 0); | |
| 222 | 251 | zUsername = P("u"); |
| 223 | 252 | zPasswd = P("p"); |
| 224 | 253 | anonFlag = P("anon")!=0; |
| 225 | 254 | if( P("out")!=0 ){ |
| 226 | 255 | /* To logout, change the cookie value to an empty string */ |
| 227 | 256 | const char *zCookieName = login_cookie_name(); |
| 228 | 257 | cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400); |
| 229 | 258 | redirect_to_g(); |
| 230 | 259 | } |
| 231 | - if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){ | |
| 260 | + if( g.perm.Password && zPasswd | |
| 261 | + && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 | |
| 262 | + ){ | |
| 232 | 263 | /* The user requests a password change */ |
| 233 | 264 | zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0); |
| 234 | 265 | if( db_int(1, "SELECT 0 FROM user" |
| 235 | 266 | " WHERE uid=%d" |
| 236 | 267 | " AND (constant_time_cmp(pw,%Q)=0" |
| @@ -454,37 +485,10 @@ | ||
| 454 | 485 | @ </form> |
| 455 | 486 | } |
| 456 | 487 | style_footer(); |
| 457 | 488 | } |
| 458 | 489 | |
| 459 | -/* | |
| 460 | -** SQL function for constant time comparison of two values. | |
| 461 | -** Sets result to 0 if two values are equal. | |
| 462 | -*/ | |
| 463 | -static void constant_time_cmp_function( | |
| 464 | - sqlite3_context *context, | |
| 465 | - int argc, | |
| 466 | - sqlite3_value **argv | |
| 467 | -){ | |
| 468 | - const unsigned char *buf1, *buf2; | |
| 469 | - int len, i; | |
| 470 | - unsigned char rc = 0; | |
| 471 | - | |
| 472 | - assert( argc==2 ); | |
| 473 | - len = sqlite3_value_bytes(argv[0]); | |
| 474 | - if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){ | |
| 475 | - rc = 1; | |
| 476 | - }else{ | |
| 477 | - buf1 = sqlite3_value_text(argv[0]); | |
| 478 | - buf2 = sqlite3_value_text(argv[1]); | |
| 479 | - for( i=0; i<len; i++ ){ | |
| 480 | - rc = rc | (buf1[i] ^ buf2[i]); | |
| 481 | - } | |
| 482 | - } | |
| 483 | - sqlite3_result_int(context, rc); | |
| 484 | -} | |
| 485 | - | |
| 486 | 490 | /* |
| 487 | 491 | ** Attempt to find login credentials for user zLogin on a peer repository |
| 488 | 492 | ** with project code zCode. Transfer those credentials to the local |
| 489 | 493 | ** repository. |
| 490 | 494 | ** |
| 491 | 495 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -192,10 +192,37 @@ | |
| 192 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 193 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 194 | zUsername, zIpAddr, bSuccess |
| 195 | ); |
| 196 | } |
| 197 | |
| 198 | /* |
| 199 | ** WEBPAGE: login |
| 200 | ** WEBPAGE: logout |
| 201 | ** WEBPAGE: my |
| @@ -217,20 +244,24 @@ | |
| 217 | char *zSha1Pw; |
| 218 | const char *zIpAddr; /* IP address of requestor */ |
| 219 | char *zRemoteAddr; /* Abbreviated IP address of requestor */ |
| 220 | |
| 221 | login_check_credentials(); |
| 222 | zUsername = P("u"); |
| 223 | zPasswd = P("p"); |
| 224 | anonFlag = P("anon")!=0; |
| 225 | if( P("out")!=0 ){ |
| 226 | /* To logout, change the cookie value to an empty string */ |
| 227 | const char *zCookieName = login_cookie_name(); |
| 228 | cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400); |
| 229 | redirect_to_g(); |
| 230 | } |
| 231 | if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){ |
| 232 | /* The user requests a password change */ |
| 233 | zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0); |
| 234 | if( db_int(1, "SELECT 0 FROM user" |
| 235 | " WHERE uid=%d" |
| 236 | " AND (constant_time_cmp(pw,%Q)=0" |
| @@ -454,37 +485,10 @@ | |
| 454 | @ </form> |
| 455 | } |
| 456 | style_footer(); |
| 457 | } |
| 458 | |
| 459 | /* |
| 460 | ** SQL function for constant time comparison of two values. |
| 461 | ** Sets result to 0 if two values are equal. |
| 462 | */ |
| 463 | static void constant_time_cmp_function( |
| 464 | sqlite3_context *context, |
| 465 | int argc, |
| 466 | sqlite3_value **argv |
| 467 | ){ |
| 468 | const unsigned char *buf1, *buf2; |
| 469 | int len, i; |
| 470 | unsigned char rc = 0; |
| 471 | |
| 472 | assert( argc==2 ); |
| 473 | len = sqlite3_value_bytes(argv[0]); |
| 474 | if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){ |
| 475 | rc = 1; |
| 476 | }else{ |
| 477 | buf1 = sqlite3_value_text(argv[0]); |
| 478 | buf2 = sqlite3_value_text(argv[1]); |
| 479 | for( i=0; i<len; i++ ){ |
| 480 | rc = rc | (buf1[i] ^ buf2[i]); |
| 481 | } |
| 482 | } |
| 483 | sqlite3_result_int(context, rc); |
| 484 | } |
| 485 | |
| 486 | /* |
| 487 | ** Attempt to find login credentials for user zLogin on a peer repository |
| 488 | ** with project code zCode. Transfer those credentials to the local |
| 489 | ** repository. |
| 490 | ** |
| 491 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -192,10 +192,37 @@ | |
| 192 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 193 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 194 | zUsername, zIpAddr, bSuccess |
| 195 | ); |
| 196 | } |
| 197 | |
| 198 | /* |
| 199 | ** SQL function for constant time comparison of two values. |
| 200 | ** Sets result to 0 if two values are equal. |
| 201 | */ |
| 202 | static void constant_time_cmp_function( |
| 203 | sqlite3_context *context, |
| 204 | int argc, |
| 205 | sqlite3_value **argv |
| 206 | ){ |
| 207 | const unsigned char *buf1, *buf2; |
| 208 | int len, i; |
| 209 | unsigned char rc = 0; |
| 210 | |
| 211 | assert( argc==2 ); |
| 212 | len = sqlite3_value_bytes(argv[0]); |
| 213 | if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){ |
| 214 | rc = 1; |
| 215 | }else{ |
| 216 | buf1 = sqlite3_value_text(argv[0]); |
| 217 | buf2 = sqlite3_value_text(argv[1]); |
| 218 | for( i=0; i<len; i++ ){ |
| 219 | rc = rc | (buf1[i] ^ buf2[i]); |
| 220 | } |
| 221 | } |
| 222 | sqlite3_result_int(context, rc); |
| 223 | } |
| 224 | |
| 225 | /* |
| 226 | ** WEBPAGE: login |
| 227 | ** WEBPAGE: logout |
| 228 | ** WEBPAGE: my |
| @@ -217,20 +244,24 @@ | |
| 244 | char *zSha1Pw; |
| 245 | const char *zIpAddr; /* IP address of requestor */ |
| 246 | char *zRemoteAddr; /* Abbreviated IP address of requestor */ |
| 247 | |
| 248 | login_check_credentials(); |
| 249 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 250 | constant_time_cmp_function, 0, 0); |
| 251 | zUsername = P("u"); |
| 252 | zPasswd = P("p"); |
| 253 | anonFlag = P("anon")!=0; |
| 254 | if( P("out")!=0 ){ |
| 255 | /* To logout, change the cookie value to an empty string */ |
| 256 | const char *zCookieName = login_cookie_name(); |
| 257 | cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400); |
| 258 | redirect_to_g(); |
| 259 | } |
| 260 | if( g.perm.Password && zPasswd |
| 261 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 262 | ){ |
| 263 | /* The user requests a password change */ |
| 264 | zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0); |
| 265 | if( db_int(1, "SELECT 0 FROM user" |
| 266 | " WHERE uid=%d" |
| 267 | " AND (constant_time_cmp(pw,%Q)=0" |
| @@ -454,37 +485,10 @@ | |
| 485 | @ </form> |
| 486 | } |
| 487 | style_footer(); |
| 488 | } |
| 489 | |
| 490 | /* |
| 491 | ** Attempt to find login credentials for user zLogin on a peer repository |
| 492 | ** with project code zCode. Transfer those credentials to the local |
| 493 | ** repository. |
| 494 | ** |
| 495 |