+/*
+ * Try to create an account manually after an OpenID was verified
+ */
+void openid_manual_create(void)
+{
+ if (havebstr("exit_action")) {
+ do_logout();
+ return;
+ }
+
+ char buf[1024];
+ if (havebstr("newuser_action")) {
+ serv_printf("OIDC %s", bstr("name"));
+ serv_getln(buf, sizeof buf);
+ if (buf[0] == '2') {
+ char gpass[1024] = "";
+ serv_puts("SETP GENERATE_RANDOM_PASSWORD");
+ serv_getln(gpass, sizeof gpass);
+ become_logged_in(bstr("name"), &gpass[4], buf);
+ }
+ }
+
+ if (WC->logged_in) {
+ if (WC->need_regi) {
+ display_reg(1);
+ } else if (WC->need_vali) {
+ validate();
+ } else {
+ do_welcome();
+ }
+ } else {
+ display_openid_name_request(bstr("openid_url"), bstr("name"));
+ }
+
+}
+
+
+/*
+ * 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)
+{
+ char buf[1024];
+ struct wcsession *WCC = WC;
+ int already_logged_in = (WCC->logged_in) ;
+ int linecount = 0;
+ char result[128] = "";
+ char username[128] = "";
+ char password[128] = "";
+ char logged_in_response[1024] = "";
+ char claimed_id[1024] = "";
+
+ if (havebstr("openid.mode")) {
+ if (!strcasecmp(bstr("openid.mode"), "id_res")) {
+
+ serv_puts("OIDF");
+ serv_getln(buf, sizeof buf);
+
+ if (buf[0] == '8') {
+ urlcontent *u;
+ void *U;
+ long HKLen;
+ const char *HKey;
+ HashPos *Cursor;
+
+ Cursor = GetNewHashPos ();
+ 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 (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
+ if (linecount == 0) safestrncpy(result, buf, sizeof result);
+ if (!strcasecmp(result, "authenticate")) {
+ if (linecount == 1) {
+ safestrncpy(username, buf, sizeof username);
+ }
+ else if (linecount == 2) {
+ safestrncpy(password, buf, sizeof password);
+ }
+ else if (linecount == 3) {
+ safestrncpy(logged_in_response, buf,
+ sizeof logged_in_response);
+ }
+ }
+ else if (!strcasecmp(result, "verify_only")) {
+ if (linecount == 1) {
+ safestrncpy(claimed_id, buf, sizeof claimed_id);
+ }
+ if (linecount == 2) {
+ safestrncpy(username, buf, sizeof username);
+ }
+ }
+ ++linecount;
+ }
+ }
+ }
+ }
+
+ /* If we were already logged in, this was an attempt to associate an OpenID account */
+ if (already_logged_in) {
+ display_openids();
+ 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(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(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."));
+ }
+
+}
+
+
+/*
+ * 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
+ */