+
+/*
+ * Perform authentication using OpenID
+ * assemble the checkid_setup request and then redirect to the user's identity provider
+ */
+void do_openid_login(void)
+{
+ char buf[4096];
+
+ if (havebstr("language")) {
+ set_selected_language(bstr("language"));
+ go_selected_language();
+ }
+
+ if (havebstr("exit_action")) {
+ do_logout();
+ return;
+ }
+ if (havebstr("login_action")) {
+ snprintf(buf, sizeof buf,
+ "OIDS %s|%s://%s/finalize_openid_login|%s://%s",
+ bstr("openid_url"),
+ (is_https ? "https" : "http"), WC->http_host,
+ (is_https ? "https" : "http"), WC->http_host
+ );
+
+ serv_puts(buf);
+ serv_getln(buf, sizeof buf);
+ if (buf[0] == '2') {
+ lprintf(CTDL_DEBUG, "OpenID server contacted; redirecting to %s\n", &buf[4]);
+ http_redirect(&buf[4]);
+ return;
+ }
+ else {
+ display_openid_login(&buf[4]);
+ return;
+ }
+ }
+
+ /* If we get to this point then something failed. */
+ display_openid_login(_("Your password was not accepted."));
+}
+
+/*
+ * Complete the authentication using OpenID
+ * This function handles the positive or negative assertion from the user's Identity Provider
+ */
+void finalize_openid_login(void)
+{
+ StrBuf *Buf;
+ wcsession *WCC = WC;
+ int already_logged_in = (WCC->logged_in) ;
+ int linecount = 0;
+ StrBuf *result = NULL;
+ StrBuf *username = NULL;
+ StrBuf *password = NULL;
+ StrBuf *logged_in_response = NULL;
+ StrBuf *claimed_id = NULL;
+
+ if (havebstr("openid.mode")) {
+ if (!strcasecmp(bstr("openid.mode"), "id_res")) {
+ Buf = NewStrBuf();
+ serv_puts("OIDF");
+ StrBuf_ServGetln(Buf);
+ if (GetServerStatus(Buf, NULL) == 8) {
+ urlcontent *u;
+ void *U;
+ long HKLen;
+ const char *HKey;
+ HashPos *Cursor;
+
+ Cursor = GetNewHashPos (WCC->urlstrings, 0);
+ while (GetNextHashPos(WCC->urlstrings, Cursor, &HKLen, &HKey, &U)) {
+ u = (urlcontent*) U;
+ if (!strncasecmp(u->url_key, "openid.", 7)) {
+ serv_printf("%s|%s", &u->url_key[7], ChrPtr(u->url_data));
+ }
+ }
+
+ serv_puts("000");
+
+ linecount = 0;
+ while (StrBuf_ServGetln(Buf),
+ (StrLength(Buf)==3) &&
+ !strcmp(ChrPtr(Buf), "000"))
+ {
+ if (linecount == 0) result = NewStrBufDup(Buf);
+ if (!strcasecmp(ChrPtr(result), "authenticate")) {
+ if (linecount == 1) {
+ username = NewStrBufDup(Buf);
+ }
+ else if (linecount == 2) {
+ password = NewStrBufDup(Buf);
+ }
+ else if (linecount == 3) {
+ logged_in_response = NewStrBufDup(Buf);
+ }
+ }
+ else if (!strcasecmp(ChrPtr(result), "verify_only")) {
+ if (linecount == 1) {
+ claimed_id = NewStrBufDup(Buf);
+ }
+ if (linecount == 2) {
+ username = NewStrBufDup(Buf);
+ }
+ }
+ ++linecount;
+ }
+ }
+ FreeStrBuf(&Buf);
+ }
+ }
+
+ /* If we were already logged in, this was an attempt to associate an OpenID account */
+ if (already_logged_in) {
+ display_openids();
+ FreeStrBuf(&result);
+ FreeStrBuf(&username);
+ FreeStrBuf(&password);
+ FreeStrBuf(&claimed_id);
+ FreeStrBuf(&logged_in_response);
+ return;
+ }
+
+ /* If this operation logged us in, either by connecting with an existing account or by
+ * auto-creating one using Simple Registration Extension, we're already on our way.
+ */
+ if (!strcasecmp(ChrPtr(result), "authenticate")) {
+ become_logged_in(username, password, logged_in_response);
+ }
+
+ /* The specified OpenID was verified but the desired user name was either not specified via SRI
+ * or conflicts with an existing user. Either way the user will need to specify a new name.
+ */
+
+ else if (!strcasecmp(ChrPtr(result), "verify_only")) {
+ display_openid_name_request(claimed_id, username);
+ }
+
+ /* Did we manage to log in? If so, continue with the normal flow... */
+ if (WC->logged_in) {
+ if (WC->need_regi) {
+ display_reg(1);
+ } else {
+ do_welcome();
+ }
+ } else {
+ display_openid_login(_("Your password was not accepted."));
+ }
+
+ FreeStrBuf(&result);
+ FreeStrBuf(&username);
+ FreeStrBuf(&password);
+ FreeStrBuf(&claimed_id);
+ FreeStrBuf(&logged_in_response);
+}
+
+
+/*
+ * Display a welcome screen to the user.
+ *
+ * If this is the first time login, and the web based setup is enabled,
+ * lead the user through the setup routines
+ */