Check-in [9c952d247e]
Not logged in
Overview

SHA1 Hash:9c952d247e5164a53ae2c24d5e0068d45e72e72e
Date: 2007-07-31 22:59:31
User: drh
Comment:Separate "nobody" and "anonymous" logins.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/login.c from [a6b6c1f3f9] to [8a96b84fb6].

@@ -21,10 +21,30 @@
 **   http://www.hwaci.com/drh/
 **
 *******************************************************************************
 **
 ** 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>
 
@@ -42,10 +62,11 @@
 ** Generate the login page
 */
 void login_page(void){
   const char *zUsername, *zPasswd, *zGoto;
   const char *zNew1, *zNew2;
+  const char *zAnonPw;
   char *zErrMsg = "";
 
   login_check_credentials();
   zUsername = P("u");
   zPasswd = P("p");
@@ -53,11 +74,11 @@
   if( P("out")!=0 ){
     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 =
          @ <p><font color="red">
@@ -78,36 +99,39 @@
       );
       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.
          @ </font></p>
       ;
     }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");
   @ %s(zErrMsg)
@@ -127,32 +151,40 @@
   @ <tr>
   @   <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
   }
   @ 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>
     @ <form action="login" method="POST">
@@ -184,11 +216,11 @@
   const char *zCookie;
   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
   ** user credentials.
@@ -198,45 +230,50 @@
         && db_get_int("authenticate-localhost",1)==0 ){
     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"
             "   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);
 }
 
 /*
 ** Set the global capability flags based on a capability string.

Modified src/main.c from [fa34f0baa1] to [21f5fffa72].

@@ -74,11 +74,10 @@
   char *urlUser;          /* User id for http: */
   char *urlPasswd;        /* Password for http: */
   char *urlCanonical;     /* Canonical representation of the URL */
 
   const char *zLogin;     /* Login name.  "" if not logged in. */
-  int isAnon;             /* True if logged in anoymously */
   int noPswd;             /* Logged in without password (on 127.0.0.1) */
   int userUid;            /* Integer user id */
 
   /* Information used to populate the RCVFROM table */
   int rcvid;              /* The rcvid.  0 if not yet defined. */

Modified src/setup.c from [91d49b89a0] to [288da0d25b].

@@ -81,11 +81,11 @@
 void setup_ulist(void){
   Stmt s;
 
   style_footer();
   login_check_credentials();
-  if( !g.okWrite || g.isAnon ){
+  if( !g.okSetup ){
     login_needed();
     return;
   }
 
   style_submenu_element("Add", "Add User", "setup_uedit");
@@ -371,24 +371,27 @@
   @ formats, and change system defaults.  But only the <b>Setup</b> user
   @ is able to change the repository to
   @ which this program is linked.
   @ </p></li>
   @
-  if( zId==0 || strcmp(zId,"anonymous")==0 ){
-    @ <li><p>
-    @ No login is required for user "<b>anonymous</b>".  The capabilities
-    @ of this user are available to anyone without supplying a username or
-    @ password.  To disable anonymous access, make sure there is no user
-    @ with an ID of <b>anonymous</b>.
-    @ </p></li>
-    @
-    @ <li><p>
-    @ The password for the "<b>anonymous</b>" user is used for anonymous
-    @ access.  The recommended value for the anonymous password
-    @ is "anonymous".
-    @ </p></li>
-  }
+  @ <li><p>
+  @ No login is required for user "<b>nobody</b>".  The capabilities
+  @ of this user are available to anyone without supplying a username or
+  @ password.  To disable nobody access, make sure there is no user
+  @ with an ID of <b>nobody</b> or that the nobody user has no
+  @ capabilities enabled.  The password for the noloing user is ignore.
+  @ </p></li>
+  @
+  @ <li><p>
+  @ Login is required for user "<b>anonymous</b>" but the password
+  @ is displayed on the login screen beside the password entry box
+  @ so anybody who can read should be able to login as anonymous.
+  @ On the other hand, spiders and web-crawlers will typically not
+  @ be able to login.  Set the capabilities of the anonymous user
+  @ to things that you want any human to be able to do, but no any
+  @ spider.
+  @ </p></li>
   @ </form>
   style_footer();
 }
 
 

Modified src/style.c from [7b2fdcfed5] to [ed5f94f215].

@@ -76,11 +76,11 @@
   @ <body bgcolor="white">
   @ <hr size="1">
   @ <table border="0" cellpadding="0" cellspacing="0" width="100%%">
   @ <tr><td valign="top" align="left">
   @ <big><big><b>%s(zTitle)</b></big></big><br>
-  if( g.zLogin==0 || g.zLogin[0]==0 ){
+  if( g.zLogin==0 ){
     @ <small>not logged in</small>
     zLogInOut = "Login";
   }else{
     @ <small>logged in as %h(g.zLogin)</small>
   }