@@ -22,8 +22,28 @@
**
*******************************************************************************
**
** This file contains code for generating the login and logout screens.
+**
+** Notes:
+**
+** There are two special-case user-ids: "anonymous" and "nobody".
+** The capabilities of the nobody user are available to anyone,
+** regardless of whether or not they are logged in. The capabilities
+** of anonymous are only available after logging in, but the login
+** screen displays the password for the anonymous login, so this
+** should not prevent a human user from doing so.
+**
+** The nobody user has capabilities that you want spiders to have.
+** The anonymous user has capabilities that you want people without
+** logins to have.
+**
+** Of course, a sophisticated spider could easily circumvent the
+** anonymous login requirement and walk the website. But that is
+** not really the point. The anonymous login keeps search-engine
+** crawlers and site download tools like wget from walking change
+** logs and downloading diffs of very version of the archive that
+** has ever existed, and things like that.
*/
#include "config.h"
#include "login.h"
#include <time.h>
@@ -43,8 +63,9 @@
*/
void login_page(void){
const char *zUsername, *zPasswd, *zGoto;
const char *zNew1, *zNew2;
+ const char *zAnonPw;
char *zErrMsg = "";
login_check_credentials();
zUsername = P("u");
@@ -54,9 +75,9 @@
const char *zCookieName = login_cookie_name();
cgi_set_cookie(zCookieName, "", 0, -86400);
cgi_redirect(zGoto);
}
- if( !g.isAnon && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
+ 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 =
@@ -79,13 +100,13 @@
cgi_redirect("index");
return;
}
}
- if( zUsername!=0 && zPasswd!=0 && strcmp(zUsername,"anonymous")!=0 ){
+ if( zUsername!=0 && zPasswd!=0 ){
int uid = db_int(0,
"SELECT uid FROM user"
" WHERE login=%Q AND pw=%Q", zUsername, zPasswd);
- if( uid<=0 ){
+ if( uid<=0 || strcmp(zUsername,"nobody")==0 ){
sleep(1);
zErrMsg =
@ <p><font color="red">
@ You entered an unknown user or an incorrect password.
@@ -93,20 +114,23 @@
;
}else{
char *zCookie;
const char *zCookieName = login_cookie_name();
- const char *zIpAddr = PD("REMOTE_ADDR","nil");
const char *zExpire = db_get("cookie-expire","8766");
- int expires;
-
- zCookie = db_text(0, "SELECT '%d/' || hex(randomblob(25))", uid);
- expires = atoi(zExpire)*3600;
- 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
- );
+ int expires = atoi(zExpire)*3600;
+ const char *zIpAddr = PD("REMOTE_ADDR","nil");
+
+ if( strcmp(zUsername, "anonymous")==0 ){
+ cgi_set_cookie(zCookieName, "anonymous", 0, expires);
+ }else{
+ 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
+ );
+ }
cgi_redirect(zGoto);
}
}
style_header("Login/Logout");
@@ -128,9 +152,9 @@
@ <td></td>
@ <td><input type="submit" name="in" value="Login"></td>
@ </tr>
@ </table>
- if( g.isAnon || g.zLogin==0 || g.zLogin[0]==0 ){
+ if( g.zLogin==0 ){
@ <p>To login
}else{
@ <p>You are current logged in as <b>%h(g.zLogin)</b></p>
@ <p>To change your login to a different user
@@ -138,20 +162,28 @@
@ enter the user-id and password at the left and press the
@ "Login" button. Your user name will be stored in a browser cookie.
@ You must configure your web browser to accept cookies in order for
@ the login to take.</p>
- if( db_exists("SELECT uid FROM user WHERE login='anonymous'") ){
- @ <p>This server is configured to allow limited access to users
- @ who are not logged in.</p>
+ if( g.zLogin==0 ){
+ zAnonPw = db_text(0, "SELECT pw FROM user"
+ " WHERE login='anonymous'"
+ " AND cap!=''");
+ if( zAnonPw ){
+ @ <p>If you do not have a user-id, enter "<b>anonymous</b>" with a
+ @ password of "<b>%h(zAnonPw)</b>".</p>
+ }else{
+ @ <p>A valid user-id and password is required. Anonymous access
+ @ is not allowed on this installation.</p>
+ }
}
- if( !g.isAnon ){
+ if( g.zLogin ){
@ <br clear="both"><hr>
@ <p>To log off the system (and delete your login cookie)
@ press the following button:<br>
@ <input type="submit" name="out" value="Logout"></p>
}
@ </form>
- if( !g.isAnon ){
+ if( g.okPassword ){
@ <br clear="both"><hr>
@ <p>To change your password, enter your old password and your
@ new password twice below then press the "Change Password"
@ button.</p>
@@ -185,9 +217,9 @@
const char *zRemoteAddr;
const char *zCap = 0;
/* Only run this check once. */
- if( g.zLogin!=0 ) return;
+ if( g.userUid!=0 ) return;
/* If the HTTP connection is coming over 127.0.0.1 and if
** local login is disabled, then there is no need to check
@@ -199,15 +231,14 @@
uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'");
g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid);
zCap = "s";
g.noPswd = 1;
- g.isAnon = 0;
}
/* Check the login cookie to see if it matches a known valid user.
*/
- if( uid==0 ){
- if( (zCookie = P(login_cookie_name()))!=0 ){
+ if( uid==0 && (zCookie = P(login_cookie_name()))!=0 ){
+ if( isdigit(zCookie[0]) ){
uid = db_int(0,
"SELECT uid FROM user"
" WHERE uid=%d"
" AND cookie=%Q"
@@ -214,28 +245,34 @@
" AND ipaddr=%Q"
" AND cexpire>julianday('now')",
atoi(zCookie), zCookie, zRemoteAddr
);
- }else{
+ }else if( zCookie[0]=='a' ){
uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'");
}
}
if( uid==0 ){
- g.isAnon = 1;
- g.zLogin = "";
- zCap = db_get("nologin-cap","onrj");
- }else if( zCap==0 ){
- Stmt s;
- db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
- db_step(&s);
- g.zLogin = db_column_malloc(&s, 0);
- zCap = db_column_malloc(&s, 1);
- g.isAnon = 0;
- db_finalize(&s);
+ uid = db_int(0, "SELECT uid FROM user WHERE login='nobody'");
+ if( uid==0 ){
+ uid = -1;
+ zCap = "";
+ }
+ }
+ if( zCap==0 ){
+ if( uid ){
+ Stmt s;
+ db_prepare(&s, "SELECT login, cap FROM user WHERE uid=%d", uid);
+ db_step(&s);
+ g.zLogin = db_column_malloc(&s, 0);
+ zCap = db_column_malloc(&s, 1);
+ db_finalize(&s);
+ }
+ if( zCap==0 ){
+ zCap = "";
+ }
}
g.userUid = uid;
-
login_set_capabilities(zCap);
}
/*