#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.
*
- * 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
* (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
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;
- size_t client_res_len;
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);
- 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) {
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);
- 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
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;
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) {
free(tokens);
return result;
}
-
#endif