Permalink
Browse files

Changing prototol to be two step. Server now transmits email adderss …

…back to client. Updating valid_until to expires.
  • Loading branch information...
1 parent d53df96 commit b0c2638cb6d400df9b1d4719d6bbfe3ee0f7de56 @ozten committed Nov 3, 2011
Showing with 173 additions and 90 deletions.
  1. +11 −1 README.md
  2. +1 −1 Vagrantfile
  3. +0 −25 browserid_debug.html
  4. +129 −34 plugins/browserid.c
  5. +12 −13 plugins/session.c
  6. +12 −9 plugins/verifier.c
  7. +7 −7 plugins/verifier.h
  8. +1 −0 test/curl_main.c
View
@@ -114,8 +114,18 @@ Do you see BROWSER-ID in the list of SASL client and server mechanisms?
### OpenLDAP (slapd) ###
+Setup:
+
sudo cp configs/slapd.conf /usr/lib/sasl2
- ldapwhoami -Y BROWSER-ID -I
+ # restart slapd
+ cd test/www/
+ python -m SimpleHTTPServer 8001
+
+Each time
+
+ # request http://localhost:8001 in your browser and do BID login flow
+ A=eyJjZXJ0aWZpY2F0ZXMiOlsiZXlKaGJHY2...some_real_assertion_ekdNeGhGM05CM3diUXV6UzC
+ ldapwhoami -Y BROWSER-ID -I -X $A -U 'localhost:8001'
### Sample client and server ###
If you've compiled SASL's sample/client and sample/server programs...
View
@@ -1,6 +1,6 @@
Vagrant::Config.run do |config|
- config.vm.box = "lucid32_2.box"
+ config.vm.box = "lucid32_2asdf.box"
config.vm.box_url = "http://people.mozilla.org/~aking/sasl_browserid/lucid32_2.box"
# VM localhost
View
@@ -1,25 +0,0 @@
-<html>
-<head>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
-<script src="https://browserid.org/include.js" type="text/javascript"></script>
-</head>
-<body>
-<h1>BrowserID Debug</h1>
-<div id='debug'>Loading</div>
-<script>
-$(document).ready(function () {
- $('#browserid').bind('click', function () {
- navigator.id.getVerifiedEmail(function(assertion) {
- if (assertion) {
- $('#debug').html("<code>" + assertion + "</code>");
- $('h1, img').remove();
- } else {
- $('#debug').text('Doh!');
- }
- });
- });
-});
-</script>
-<img id="browserid" src="https://browserid.org/i/sign_in_red.png" />
-</body>
-</html>
View
@@ -50,6 +50,9 @@
/* MAX_AUDIENCE 256 for max domain name length and some change for port number */
#define MAX_AUDIENCE 300
+/* MAX_AUDIENCE 256 for max domain name length and some change for port number */
+#define MAX_EMAIL 254
+
static const char plugin_id[] = "$Id: browserid.c,v 1.180 2011/08/11 17:00:00 mel Exp $";
struct context;
@@ -84,6 +87,23 @@ static int browserid_server_mech_new(void *glob_context,
return SASL_OK;
}
+static int _transmit_email(sasl_server_params_t *sparams,
+ const char **serverout,
+ unsigned *serveroutlen,
+ char *email)
+{
+ *serveroutlen = strlen(email);
+ *serverout = sparams->utils->malloc(*serveroutlen);
+ if (*serverout == NULL) {
+ MEMERROR(sparams->utils);
+ return SASL_NOMEM;
+ }
+ strcpy(*serverout, email);
+ syslog(LOG_DEBUG, "Sending [%s] back to client", *serverout);
+ return SASL_OK;
+}
+
+
/**
* Core of the server plugin.
*/
@@ -104,7 +124,7 @@ static int browserid_server_mech_step(void *conn_context,
struct browserid_response_t *browserid_response;
char email[1024];
- syslog(LOG_DEBUG, "browserid_server_mech_step clientinlen=%d",
+ syslog(LOG_DEBUG, "browserid_server_mech_step clientinlen=%d",
clientinlen);
/* should have received assertion NUL audience */
@@ -113,7 +133,6 @@ static int browserid_server_mech_step(void *conn_context,
assertion = clientin;
-
if (strlen(assertion) > MAX_ASSERTION) {
syslog(LOG_ERR, "Client send a longer assertion [%u] that we "
"expected, failing", strlen(assertion));
@@ -138,11 +157,11 @@ static int browserid_server_mech_step(void *conn_context,
audience_len = (unsigned) (clientin + lup - audience);
if (audience_len > MAX_AUDIENCE) {
syslog(LOG_ERR, "Client send a longer audience [%u] that "
- "we expected, failing",
+ "we expected, failing",
strlen(audience));
return SASL_BADPROT;
}
- syslog(LOG_DEBUG, "lup = %d clientinlen = %d", lup,
+ syslog(LOG_DEBUG, "lup = %d clientinlen = %d", lup,
clientinlen);
if (lup != clientinlen) {
@@ -165,39 +184,44 @@ static int browserid_server_mech_step(void *conn_context,
syslog(LOG_DEBUG, "Server side, we've got ASSERTION[%s] AUDIENCE[%s]",
assertion, audience_copy);
-
if (check_session(sparams->utils, assertion, (char *)&email) == 1) {
- syslog(LOG_DEBUG, "Got email = %s", email);
+ syslog(LOG_DEBUG, "Found email = %s in session", email);
/* set user into the session or whatever... */
result = sparams->canon_user(sparams->utils->conn,
email, 0,
- SASL_CU_AUTHID | SASL_CU_AUTHZID,
+ SASL_CU_AUTHID | SASL_CU_AUTHZID,
oparams);
+ _transmit_email(sparams, serverout, serveroutlen, email);
} else {
+ syslog(LOG_DEBUG, "No session hit, using verifier");
browserid_response = malloc(sizeof(struct browserid_response_t));
- browserid_verify(sparams->utils, browserid_response,
+ browserid_verify(sparams->utils, browserid_response,
assertion, audience_copy);
if (strcasecmp(browserid_response->status, "okay") == 0) {
syslog(LOG_DEBUG, "Yes, we're all good! %s %s %s until %llu",
browserid_response->email,
browserid_response->audience,
browserid_response->issuer,
- browserid_response->valid_until);
- create_session(sparams->utils, assertion,
+ browserid_response->expires);
+ create_session(sparams->utils, assertion,
browserid_response->email);
result = sparams->canon_user(sparams->utils->conn,
browserid_response->email, 0,
SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+
+
+ _transmit_email(sparams, serverout, serveroutlen, browserid_response->email);
+
if (result != SASL_OK) {
_plug_free_string(sparams->utils, &audience_copy);
free(browserid_response);
return result;
}
} else {
- syslog(LOG_ERR, "No dice, STATUS=[%s] REASON=[%s]",
- browserid_response->status,
+ syslog(LOG_ERR, "No dice, STATUS=[%s] REASON=[%s]",
+ browserid_response->status,
browserid_response->reason);
SETERROR(sparams->utils, browserid_response->reason);
@@ -206,7 +230,6 @@ static int browserid_server_mech_step(void *conn_context,
return SASL_BADAUTH;
}
-
free(browserid_response);
}
_plug_free_string(sparams->utils, &audience_copy);
@@ -278,6 +301,7 @@ int browserid_server_plug_init(sasl_utils_t *utils,
/***************************** Client Section *****************************/
typedef struct client_context {
+ int state;
char *out_buf;
unsigned out_buf_len;
} client_context_t;
@@ -300,17 +324,15 @@ static int browserid_client_mech_new(void *glob_context,
}
memset(context, 0, sizeof(client_context_t));
-
+ context->state = 1;
*conn_context = context;
return SASL_OK;
}
/**
- * Core of the client plugin. Does client side authentication... which
- * is none. Probably we need a two step where we get the server
- * to figure out the hard stuff.
+ * Figure out the user's assertion and audience then send to the server.
*/
-static int browserid_client_mech_step(void *conn_context,
+static int browserid_client_mech_step1(void *conn_context,
sasl_client_params_t *params,
const char *serverin,
unsigned serverinlen,
@@ -326,7 +348,7 @@ static int browserid_client_mech_step(void *conn_context,
int result;
char *p;
- syslog(LOG_DEBUG, "browserid_client_mech_new");
+ syslog(LOG_DEBUG, "browserid_client_mech_step1");
if (!params || !clientout || !clientoutlen || !oparams) {
PARAMERROR( params->utils );
@@ -405,21 +427,9 @@ static int browserid_client_mech_step(void *conn_context,
"(%u), failing", strlen(browser_audience));
return SASL_BADPARAM;
}
- syslog(LOG_DEBUG, "YO ASSERTION=[%s] AUDIENCE=[%s]",
+ syslog(LOG_DEBUG, "YO ASSERTION=[%s] AUDIENCE=[%s]",
browser_assertion, browser_audience);
- result = params->canon_user(params->utils->conn, browser_assertion, 0,
- SASL_CU_AUTHZID, oparams);
-
- if (result != SASL_OK) goto cleanup;
-
- result = params->canon_user(params->utils->conn, browser_audience, 0,
- SASL_CU_AUTHID, oparams);
-
- if (result != SASL_OK) goto cleanup;
-
- syslog(LOG_DEBUG, "Got passed canon_user");
-
/* send assertion NUL audience NUL */
*clientoutlen = (strlen(browser_assertion) + 1 + strlen(browser_audience));
@@ -438,7 +448,53 @@ static int browserid_client_mech_step(void *conn_context,
memcpy(++p, oparams->authid, oparams->alen);
p += oparams->alen;
- *clientout = context->out_buf;
+ p = params->utils->malloc(*clientoutlen);
+ strcpy(p, browser_assertion);
+ p += strlen(browser_assertion) + 1;
+ strcpy(p, browser_audience);
+ p -= strlen(browser_assertion) + 1;
+ *clientout = p;
+
+ context->state = 2;
+ return SASL_CONTINUE;
+
+ cleanup:
+ return result;
+}
+
+/**
+ * Read email address from server and canonicalize the userid and authname.
+ */
+static int browserid_client_mech_step2(void *conn_context,
+ sasl_client_params_t *params,
+ const char *serverin,
+ unsigned serverinlen,
+ sasl_interact_t **prompt_need,
+ const char **clientout,
+ unsigned *clientoutlen,
+ sasl_out_params_t *oparams)
+{
+ client_context_t *context = (client_context_t *) conn_context;
+ char *email;
+ int result;
+
+ syslog(LOG_DEBUG, "browserid_client_mech_step2 serverinlen=%d", serverinlen);
+
+ /* should have received email NUL */
+ email = serverin;
+
+ if (strlen(email) > MAX_EMAIL) {
+ syslog(LOG_ERR, "Server sent a longer email [%u] that we "
+ "expected, failing", strlen(email));
+ return SASL_BADPROT;
+ }
+
+ syslog(LOG_DEBUG, "client step2 seeing email=[%s]", email);
+
+ result = params->canon_user(params->utils->conn, email, 0,
+ SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+
+ if (result != SASL_OK) goto cleanup;
oparams->doneflag = 1;
oparams->mech_ssf = 0;
@@ -452,7 +508,46 @@ static int browserid_client_mech_step(void *conn_context,
cleanup:
/*return result;*/
- return SASL_OK;
+ return result;
+}
+/**
+ * Core of the client plugin. Does client side authentication... which
+ * is none. Probably we need a two step where we get the server
+ * to figure out the hard stuff.
+ */
+static int browserid_client_mech_step(void *conn_context,
+ sasl_client_params_t *params,
+ const char *serverin,
+ unsigned serverinlen,
+ sasl_interact_t **prompt_need,
+ const char **clientout,
+ unsigned *clientoutlen,
+ sasl_out_params_t *oparams)
+{
+ client_context_t *context = (client_context_t *) conn_context;
+ switch (context->state) {
+ case 1:
+ return browserid_client_mech_step1(conn_context,
+ params,
+ serverin,
+ serverinlen,
+ prompt_need,
+ clientout,
+ clientoutlen,
+ oparams);
+ case 2:
+ return browserid_client_mech_step2(conn_context,
+ params,
+ serverin,
+ serverinlen,
+ prompt_need,
+ clientout,
+ clientoutlen,
+ oparams);
+ default:
+ syslog(LOG_ERR, "Unknown state in client step %d", context->state);
+ return SASL_BADPARAM;
+ }
}
/**
Oops, something went wrong.

0 comments on commit b0c2638

Please sign in to comment.