From 3036551977f003d9ef3bc15e682201272f400840 Mon Sep 17 00:00:00 2001 Message-Id: <3036551977f003d9ef3bc15e682201272f400840.1715486231.git.mdw@distorted.org.uk> From: Mark Wooding Date: Mon, 31 Dec 2007 10:26:52 +0000 Subject: [PATCH] 'confirm' now logs the user in (and sends back their username so the CGI knows who it is today). The CGI then gets a new cookie so that the user continues being logged in. Organization: Straylight/Edgeware From: rjk@greenend.org.uk <> This is a bit of a change from the original design but does save the user a bit of time. Also improved some of the associated web page text. --- lib/client.c | 8 +++++++- lib/trackdb.c | 21 +++++++++++++++++++-- lib/trackdb.h | 3 ++- server/dcgi.c | 11 +++++++++++ server/server.c | 30 +++++++++++++++++++++++------- templates/options.labels | 8 ++++---- 6 files changed, 66 insertions(+), 15 deletions(-) diff --git a/lib/client.c b/lib/client.c index 1dac922..aabea87 100644 --- a/lib/client.c +++ b/lib/client.c @@ -1139,7 +1139,13 @@ int disorder_register(disorder_client *c, const char *user, * @return 0 on success, non-0 on error */ int disorder_confirm(disorder_client *c, const char *confirm) { - return disorder_simple(c, 0, "confirm", confirm, (char *)0); + char *u; + int rc; + + if(!(rc = dequote(disorder_simple(c, &u, "confirm", confirm, (char *)0), + &u))) + c->user = u; + return rc; } /** @brief Make a cookie for this login diff --git a/lib/trackdb.c b/lib/trackdb.c index 648189f..8239a69 100644 --- a/lib/trackdb.c +++ b/lib/trackdb.c @@ -2705,11 +2705,20 @@ char **trackdb_listusers(void) { return v->vec; } +/** @brief Confirm a user registration + * @param user Username + * @param confirmation Confirmation string + * @param rightsp Where to put user rights + * @param tid Transaction ID + * @return 0 on success, non-0 on error + */ static int trackdb_confirm_tid(const char *user, const char *confirmation, + rights_type *rightsp, DB_TXN *tid) { const char *stored_confirmation; struct kvp *k; int e; + const char *rights; if((e = trackdb_getdata(trackdb_usersdb, user, &k, tid))) return e; @@ -2718,6 +2727,12 @@ static int trackdb_confirm_tid(const char *user, const char *confirmation, /* DB claims -30,800 to -30,999 so -1 should be a safe bet */ return -1; } + if(!(rights = kvp_get(k, "rights"))) { + error(0, "no rights for unconfirmed user '%s'", user); + return -1; + } + if(parse_rights(rights, rightsp, 1)) + return -1; if(strcmp(confirmation, stored_confirmation)) { error(0, "wrong confirmation string for user '%s'", user); return -1; @@ -2730,12 +2745,14 @@ static int trackdb_confirm_tid(const char *user, const char *confirmation, /** @brief Confirm a user registration * @param user Username * @param confirmation Confirmation string + * @param rightsp Where to put user rights * @return 0 on success, non-0 on error */ -int trackdb_confirm(const char *user, const char *confirmation) { +int trackdb_confirm(const char *user, const char *confirmation, + rights_type *rightsp) { int e; - WITH_TRANSACTION(trackdb_confirm_tid(user, confirmation, tid)); + WITH_TRANSACTION(trackdb_confirm_tid(user, confirmation, rightsp, tid)); switch(e) { case 0: info("registration confirmed for user '%s'", user); diff --git a/lib/trackdb.h b/lib/trackdb.h index d414545..f1aae33 100644 --- a/lib/trackdb.h +++ b/lib/trackdb.h @@ -169,7 +169,8 @@ struct kvp *trackdb_getuserinfo(const char *user); int trackdb_edituserinfo(const char *user, const char *key, const char *value); char **trackdb_listusers(void); -int trackdb_confirm(const char *user, const char *confirmation); +int trackdb_confirm(const char *user, const char *confirmation, + rights_type *rightsp); #endif /* TRACKDB_H */ diff --git a/server/dcgi.c b/server/dcgi.c index caaea64..fca4e01 100644 --- a/server/dcgi.c +++ b/server/dcgi.c @@ -563,10 +563,21 @@ static void act_confirm(cgi_sink *output, cgi_set_option("error", "noconfirm"); expand_template(ds, output, "login"); } + /* Confirm our registration */ if(disorder_confirm(ds->g->client, confirmation)) { cgi_set_option("error", "badconfirm"); expand_template(ds, output, "login"); } + /* Get a cookie */ + if(disorder_make_cookie(ds->g->client, &login_cookie)) { + cgi_set_option("error", "cookiefailed"); + expand_template(ds, output, "login"); + return; + } + /* Discard any cached data JIC */ + ds->g->flags = 0; + /* We have a new cookie */ + header_cookie(output->sink); cgi_set_option("status", "confirmed"); expand_template(ds, output, "login"); } diff --git a/server/server.c b/server/server.c index a09025e..a7fad01 100644 --- a/server/server.c +++ b/server/server.c @@ -435,10 +435,10 @@ static int c_user(struct conn *c, c->who = vec[0]; c->rights = rights; /* currently we only bother logging remote connections */ - if(strcmp(host, "local")) { + if(strcmp(host, "local")) info("S%x %s connected from %s", c->tag, vec[0], host); + else c->rights |= RIGHT__LOCAL; - } sink_writes(ev_writer_sink(c->w), "230 OK\n"); return 1; } @@ -1029,10 +1029,10 @@ static int c_cookie(struct conn *c, c->who = user; c->cookie = vec[0]; c->rights = rights; - if(strcmp(host, "local")) { + if(strcmp(host, "local")) info("S%x %s connected with cookie from %s", c->tag, user, host); + else c->rights |= RIGHT__LOCAL; - } /* Response contains username so client knows who they are acting as */ sink_printf(ev_writer_sink(c->w), "232 %s\n", quoteutf8(user)); return 1; @@ -1179,17 +1179,33 @@ static int c_confirm(struct conn *c, int attribute((unused)) nvec) { size_t nuser; char *user, *sep; + rights_type rights; + const char *host; + /* Get some kind of peer identifcation */ + if(!(host = connection_host(c))) { + sink_writes(ev_writer_sink(c->w), "530 Authentication failure\n"); + return 1; + } if(!(user = mime_base64(vec[0], &nuser)) || !(sep = memchr(user, ';', nuser))) { sink_writes(ev_writer_sink(c->w), "550 Malformed confirmation string\n"); return 1; } *sep = 0; - if(trackdb_confirm(user, vec[0])) + if(trackdb_confirm(user, vec[0], &rights)) sink_writes(ev_writer_sink(c->w), "550 Incorrect confirmation string\n"); - else - sink_writes(ev_writer_sink(c->w), "250 OK\n"); + else { + c->who = user; + c->cookie = 0; + c->rights = rights; + if(strcmp(host, "local")) + info("S%x %s confirmed from %s", c->tag, user, host); + else + c->rights |= RIGHT__LOCAL; + /* Response contains username so client knows who they are acting as */ + sink_printf(ev_writer_sink(c->w), "232 %s\n", quoteutf8(user)); + } return 1; } diff --git a/templates/options.labels b/templates/options.labels index 56e3fe6..1d9800a 100644 --- a/templates/options.labels +++ b/templates/options.labels @@ -147,10 +147,10 @@ label login.edituser "Change Details" label login.logout "Logout" # Text for login page responses -label login.loginok "Logged in OK" -label login.logoutok "Logged out OK" -label login.registered "Registered your new login" -label login.confirmed "Confirmed your new login" +label login.loginok "You are now logged in." +label login.logoutok "You are now logged out." +label login.registered "Registered your new login. Please check your email." +label login.confirmed "Confirmed your new login. You are now logged in." # for account page label account.title "DisOrder User Details" -- [mdw]