* More work on OpenID 1.1 Relying Party support
[citadel.git] / citadel / modules / openid / serv_openid_rp.c
index 488345dec5d5283cb162812e962dccee26e0fab4..fc691246f5a014ebefbdf2ef617da28d085fd30d 100644 (file)
 #include "ctdl_module.h"
 
 
+struct associate_handle {
+       char claimed_id[256];
+       char assoc_type[32];
+       time_t expires_in;
+       char assoc_handle[128];
+       char mac_key[128];
+};
+
+
+
 /* 
  * Locate a <link> tag and, given its 'rel=' parameter, return its 'href' parameter
  */
@@ -178,6 +188,83 @@ int fetch_http(char *url, char *target_buf, int maxbytes)
 }
 
 
+#define ASSOCIATE_RESPONSE_SIZE        4096
+
+/*
+ * libcurl callback function for prepare_openid_associate_request()
+ */
+size_t associate_callback(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+       char *response = (char *) stream;
+       int got_bytes = (size * nmemb);
+       int len = strlen(response);
+
+       if ((len + got_bytes + 1) < ASSOCIATE_RESPONSE_SIZE) {
+               memcpy(&response[len], ptr, got_bytes);
+               response[len+got_bytes] = 0;
+       }
+
+       return got_bytes;
+}
+
+
+/*
+ * Process the response from an "associate" request
+ */
+void process_associate_response(associate_response)
+{
+       // FIXME finish this
+}
+
+
+
+/*
+ * Establish a shared secret with an OpenID Identity Provider by sending
+ * an "associate" request.
+ */
+void prepare_openid_associate_request(char *openid_server, char *openid_delegate)
+{
+       CURL *curl;
+       CURLcode res;
+       struct curl_httppost *formpost=NULL;
+       struct curl_httppost *lastptr=NULL;
+       char associate_response[ASSOCIATE_RESPONSE_SIZE];
+
+       memset(associate_response, 0, ASSOCIATE_RESPONSE_SIZE);
+
+       curl_formadd(&formpost,
+                       &lastptr,
+                       CURLFORM_COPYNAME,      "openid.mode",
+                       CURLFORM_COPYCONTENTS,  "associate",
+                       CURLFORM_END
+       );
+
+       curl_formadd(&formpost,
+                       &lastptr,
+                       CURLFORM_COPYNAME,      "openid.session_type",
+                       CURLFORM_COPYCONTENTS,  "",
+                       CURLFORM_END
+       );
+
+       curl = curl_easy_init();
+       if (curl) {
+               curl_easy_setopt(curl, CURLOPT_URL, openid_server);
+               curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+               curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
+               curl_easy_setopt(curl, CURLOPT_WRITEDATA, associate_response);
+               curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, associate_callback);
+               curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+                       
+               curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+               res = curl_easy_perform(curl);
+               process_associate_response(associate_response);
+               curl_easy_cleanup(curl);
+       }
+       curl_formfree(formpost);
+}
+
+
+
 
 
 /*
@@ -201,7 +288,6 @@ void cmd_oid1(char *argbuf) {
 
        i = fetch_http(openid_url, buf, sizeof buf - 1);
        buf[sizeof buf - 1] = 0;
-       CtdlLogPrintf(CTDL_DEBUG, "fetch got %d bytes:\n", i);
        if (i > 0) {
                char openid_server[1024];
                char openid_delegate[1024];
@@ -219,16 +305,21 @@ void cmd_oid1(char *argbuf) {
                        safestrncpy(openid_delegate, openid_url, sizeof openid_delegate);
                }
 
-               /* Now we know where to redirect to. */
+               /* Prepare an "associate" request */
+               prepare_openid_associate_request(openid_server, openid_delegate);
 
+               /* Now we know where to redirect to. */
                char redirect_string[4096];
                char escaped_identity[1024];
                char escaped_return_to[1024];
                char escaped_trust_root[1024];
+               char escaped_sreg_optional[256];
 
                urlesc(escaped_identity, sizeof escaped_identity, openid_delegate);
                urlesc(escaped_return_to, sizeof escaped_return_to, return_to);
                urlesc(escaped_trust_root, sizeof escaped_trust_root, trust_root);
+               urlesc(escaped_sreg_optional, sizeof escaped_sreg_optional,
+                       "nickname,email,fullname,postcode,country");
 
                snprintf(redirect_string, sizeof redirect_string,
                        "%s"
@@ -236,8 +327,10 @@ void cmd_oid1(char *argbuf) {
                        "&openid_identity=%s"
                        "&openid.return_to=%s"
                        "&openid.trust_root=%s"
+                       "&openid.sreg.optional=%s"
                        ,
-                       openid_server, escaped_identity, escaped_return_to, escaped_trust_root
+                       openid_server, escaped_identity, escaped_return_to,
+                       escaped_trust_root, escaped_sreg_optional
                );
                cprintf("%d %s\n", CIT_OK, redirect_string);
                return;
@@ -255,6 +348,7 @@ CTDL_MODULE_INIT(openid_rp)
 {
        if (!threading)
        {
+               curl_global_init(CURL_GLOBAL_ALL);
                CtdlRegisterProtoHook(cmd_oid1, "OID1", "Begin OpenID checkid_setup operation");
        }