]> diplodocus.org Git - nmh/blobdiff - sbr/oauth.c
Improve these comments a bit.
[nmh] / sbr / oauth.c
old mode 100644 (file)
new mode 100755 (executable)
index e86aefe..0cc95e4
 
 #define JSON_TYPE "application/json"
 
 
 #define JSON_TYPE "application/json"
 
-/* We pretend access tokens expire 30 seconds earlier than they actually do to
+/* We pretend access tokens expire 60 seconds earlier than they actually do to
  * allow for separate processes to use and refresh access tokens.  The process
  * that uses the access token (post) has an error if the token is expired; the
  * process that refreshes the access token (send) must have already refreshed if
  * the expiration is close.
  *
  * allow for separate processes to use and refresh access tokens.  The process
  * that uses the access token (post) has an error if the token is expired; the
  * process that refreshes the access token (send) must have already refreshed if
  * the expiration is close.
  *
- * 30s is arbitrary, and hopefully is enough to allow for clock skew.
+ * 60s is arbitrary, and hopefully is enough to allow for clock skew.
  * Currently only Gmail supports XOAUTH2, and seems to always use a token
  * life-time of 3600s, but that is not guaranteed.  It is possible for Gmail to
  * issue an access token with a life-time so short that even after send
  * Currently only Gmail supports XOAUTH2, and seems to always use a token
  * life-time of 3600s, but that is not guaranteed.  It is possible for Gmail to
  * issue an access token with a life-time so short that even after send
@@ -44,7 +44,7 @@
  * (not counting header and not null-terminated) */
 #define RESPONSE_BODY_MAX 8192
 
  * (not counting header and not null-terminated) */
 #define RESPONSE_BODY_MAX 8192
 
-/* Maxium size for URLs and URI-encoded query strings, null-terminated.
+/* Maximum size for URLs and URI-encoded query strings, null-terminated.
  *
  * Actual maximum we need is based on the size of tokens (limited by
  * RESPONSE_BODY_MAX), code user copies from a web page (arbitrarily large), and
  *
  * Actual maximum we need is based on the size of tokens (limited by
  * RESPONSE_BODY_MAX), code user copies from a web page (arbitrarily large), and
@@ -127,23 +127,22 @@ static boolean get_json_strings(const char *, size_t, FILE *, ...);
 static boolean make_query_url(char *, size_t, CURL *, const char *, ...);
 static boolean post(struct curl_ctx *, const char *, const char *);
 
 static boolean make_query_url(char *, size_t, CURL *, const char *, ...);
 static boolean post(struct curl_ctx *, const char *, const char *);
 
-char *
-mh_oauth_do_xoauth(const char *user, const char *svc, FILE *log)
+int
+mh_oauth_do_xoauth(const char *user, const char *svc, unsigned char **oauth_res,
+                  size_t *oauth_res_len, FILE *log)
 {
     mh_oauth_ctx *ctx;
     mh_oauth_cred *cred;
     char *fn;
     int failed_to_lock = 0;
     FILE *fp;
 {
     mh_oauth_ctx *ctx;
     mh_oauth_cred *cred;
     char *fn;
     int failed_to_lock = 0;
     FILE *fp;
-    size_t client_res_len;
     char *client_res;
     char *client_res;
-    char *client_res_b64;
 
     if (!mh_oauth_new (&ctx, svc)) adios(NULL, mh_oauth_get_err_string(ctx));
 
     if (log != NULL) mh_oauth_log_to(stderr, ctx);
 
 
     if (!mh_oauth_new (&ctx, svc)) adios(NULL, mh_oauth_get_err_string(ctx));
 
     if (log != NULL) mh_oauth_log_to(stderr, ctx);
 
-    fn = getcpy(mh_oauth_cred_fn(ctx));
+    fn = getcpy(mh_oauth_cred_fn(svc));
     fp = lkfopendata(fn, "r+", &failed_to_lock);
     if (fp == NULL) {
         if (errno == ENOENT) {
     fp = lkfopendata(fn, "r+", &failed_to_lock);
     if (fp == NULL) {
         if (errno == ENOENT) {
@@ -183,18 +182,14 @@ mh_oauth_do_xoauth(const char *user, const char *svc, FILE *log)
     free(fn);
 
     /* XXX writeBase64raw modifies the source buffer!  make a copy */
     free(fn);
 
     /* XXX writeBase64raw modifies the source buffer!  make a copy */
-    client_res = getcpy(mh_oauth_sasl_client_response(&client_res_len, user,
+    client_res = getcpy(mh_oauth_sasl_client_response(oauth_res_len, user,
                                                       cred));
     mh_oauth_cred_free(cred);
     mh_oauth_free(ctx);
                                                       cred));
     mh_oauth_cred_free(cred);
     mh_oauth_free(ctx);
-    client_res_b64 = mh_xmalloc(((((client_res_len) + 2) / 3 ) * 4) + 1);
-    if (writeBase64raw((unsigned char *)client_res, client_res_len,
-                       (unsigned char *)client_res_b64) != OK) {
-        adios(NULL, "base64 encoding of XOAUTH2 client response failed");
-    }
-    free(client_res);
 
 
-    return client_res_b64;
+    *oauth_res = (unsigned char *) client_res;
+
+    return OK;
 }
 
 static boolean
 }
 
 static boolean
@@ -569,36 +564,6 @@ mh_oauth_cred_free(mh_oauth_cred *cred)
     free(cred);
 }
 
     free(cred);
 }
 
-const char *
-mh_oauth_cred_fn(mh_oauth_ctx *ctx)
-{
-    char *result, *result_if_allocated;
-    const char *svc = ctx->svc.name;
-
-    char *component = mh_oauth_node_name_for_svc("credential-file", svc);
-    result = context_find(component);
-    free(component);
-
-    if (result == NULL) {
-        result = mh_xmalloc(sizeof "oauth-" - 1
-                            + strlen(svc)
-                            + 1 /* '\0' */);
-        sprintf(result, "oauth-%s", svc);
-        result_if_allocated = result;
-    } else {
-        result_if_allocated = NULL;
-    }
-
-    if (result[0] != '/') {
-        const char *tmp = m_maildir(result);
-        free(result_if_allocated);
-        result = getcpy(tmp);
-    }
-
-    free(ctx->cred_fn);
-    return ctx->cred_fn = result;
-}
-
 /* for loading multi-user cred files */
 struct user_creds {
     mh_oauth_cred *creds;
 /* for loading multi-user cred files */
 struct user_creds {
     mh_oauth_cred *creds;
@@ -991,6 +956,14 @@ post(struct curl_ctx *ctx, const char *url, const char *req_body)
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx);
 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx);
 
+    if (strncmp(url, "http://127.0.0.1:", 17) == 0) {
+        /* Hack:  on Cygwin, curl doesn't fail to connect with ECONNREFUSED.
+           Instead, it waits to timeout.  So set a really short timeout, but
+           just on localhost (for convenience of the user, and the test
+           suite). */
+        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 2L);
+    }
+
     status = curl_easy_perform(curl);
     /* first check for error from callback */
     if (ctx->too_big) {
     status = curl_easy_perform(curl);
     /* first check for error from callback */
     if (ctx->too_big) {
@@ -1165,5 +1138,4 @@ get_json_strings(const char *input, size_t input_len, FILE *log, ...)
     free(tokens);
     return result;
 }
     free(tokens);
     return result;
 }
-
 #endif
 #endif