diff --git a/include/curl/curl.h b/include/curl/curl.h
index e635968..e97e227 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -492,6 +492,7 @@ typedef enum {
 #define CURLAUTH_GSSNEGOTIATE (1<<2)  /* GSS-Negotiate */
 #define CURLAUTH_NTLM         (1<<3)  /* NTLM */
 #define CURLAUTH_DIGEST_IE    (1<<4)  /* Digest with IE flavour */
+#define CURLAUTH_OAUTH        (1<<5)  /* OAuth */
 #define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)  /* all fine types set */
 #define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
 
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index e35e8bb..cd4b833 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -12,7 +12,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c	\
   strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c          \
   socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c		\
   curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c	\
-  warnless.c hmac.c polarssl.c
+  warnless.c hmac.c polarssl.c http_oauth.c
 
 HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
   progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h	\
@@ -25,4 +25,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
   tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h	\
   curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h	\
   curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h	\
-  warnless.h curl_hmac.h polarssl.h
+  warnless.h curl_hmac.h polarssl.h http_oauth.h
diff --git a/lib/http.c b/lib/http.c
index d510e6a..bd455d2 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -84,6 +84,7 @@
 #include "strequal.h"
 #include "sslgen.h"
 #include "http_digest.h"
+#include "http_oauth.h"
 #include "http_ntlm.h"
 #include "http_negotiate.h"
 #include "url.h"
@@ -299,6 +300,8 @@ static bool pickoneauth(struct auth *pick)
      of preference in case of the existence of multiple accepted types. */
   if(avail & CURLAUTH_GSSNEGOTIATE)
     pick->picked = CURLAUTH_GSSNEGOTIATE;
+  else if(avail & CURLAUTH_OAUTH)
+    pick->picked = CURLAUTH_OAUTH;
   else if(avail & CURLAUTH_DIGEST)
     pick->picked = CURLAUTH_DIGEST;
   else if(avail & CURLAUTH_NTLM)
@@ -541,6 +544,15 @@ output_auth_headers(struct connectdata *conn,
   }
   else
 #endif
+  if(authstatus->picked == CURLAUTH_OAUTH) {
+    auth="OAuth";
+    result = Curl_output_oauth(conn, proxy,
+                               (const unsigned char *)request,
+                               (const unsigned char *)path);
+    if(result)
+      return result;
+  }
+  else
 #ifdef USE_NTLM
   if(authstatus->picked == CURLAUTH_NTLM) {
     auth="NTLM";
@@ -757,6 +769,23 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
   }
   else
 #endif
+    if(checkprefix("OAuth", start)) {
+      *availp |= CURLAUTH_OAUTH;
+      authp->avail |= CURLAUTH_OAUTH;
+      if(authp->picked == CURLAUTH_OAUTH) {
+        /* OAuth authentication is picked and activated */
+        CURLoauth oauth =
+          Curl_input_oauth(conn, (bool)(httpcode == 407), start);
+
+        if(CURLOAUTH_BAD != oauth)
+          data->state.authproblem = FALSE;
+        else {
+          infof(data, "Authentication problem. Ignoring this.\n");
+          data->state.authproblem = TRUE;
+        }
+      }
+    }
+    else
 #ifdef USE_NTLM
     /* NTLM support requires the SSL crypto libs */
     if(checkprefix("NTLM", start)) {
diff --git a/lib/http_oauth.c b/lib/http_oauth.c
new file mode 100644
index 0000000..9f60935
--- /dev/null
+++ b/lib/http_oauth.c
@@ -0,0 +1,295 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+/* -- WIN32 approved -- */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "rawstr.h"
+#include "curl_base64.h"
+#include "curl_md5.h"
+#include "http_oauth.h"
+#include "strtok.h"
+#include "url.h" /* for Curl_safefree() */
+#include "curl_memory.h"
+#include "easyif.h" /* included for Curl_convert_... prototypes */
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#define MAX_VALUE_LENGTH 256
+#define MAX_CONTENT_LENGTH 1024
+
+/*
+ * Return 0 on success and then the buffers are filled in fine.
+ *
+ * TODO: This function is a copy from http_digest.c and should rather be made
+ * into a common function. Possibly to be used by more/all auths.
+ *
+ * Non-zero means failure to parse.
+ */
+static int get_pair(const char *str, char *value, char *content,
+                    const char **endptr)
+{
+  int c;
+  bool starts_with_quote = FALSE;
+  bool escape = FALSE;
+
+  for(c=MAX_VALUE_LENGTH-1; (*str && (*str != '=') && c--); )
+    *value++ = *str++;
+  *value=0;
+
+  if('=' != *str++)
+    /* eek, no match */
+    return 1;
+
+  if('\"' == *str) {
+    /* this starts with a quote so it must end with one as well! */
+    str++;
+    starts_with_quote = TRUE;
+  }
+
+  for(c=MAX_CONTENT_LENGTH-1; *str && c--; str++) {
+    switch(*str) {
+    case '\\':
+      if(!escape) {
+        /* possibly the start of an escaped quote */
+        escape = TRUE;
+        *content++ = '\\'; /* even though this is an escape character, we still
+                              store it as-is in the target buffer */
+        continue;
+      }
+      break;
+    case ',':
+      if(!starts_with_quote) {
+        /* this signals the end of the content if we didn't get a starting quote
+           and then we do "sloppy" parsing */
+        c=0; /* the end */
+        continue;
+      }
+      break;
+    case '\r':
+    case '\n':
+      /* end of string */
+      c=0;
+      continue;
+    case '\"':
+      if(!escape && starts_with_quote) {
+        /* end of string */
+        c=0;
+        continue;
+      }
+      break;
+    }
+    escape = FALSE;
+    *content++ = *str;
+  }
+  *content=0;
+
+  *endptr = str;
+
+  return 0; /* all is fine! */
+}
+
+
+/* Test example headers:
+
+WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
+Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
+
+*/
+
+CURLoauth Curl_input_oauth(struct connectdata *conn,
+                           bool proxy,
+                           const char *header) /* rest of the *-authenticate:
+                                                  header */
+{
+  bool more = TRUE;
+  char *token = NULL;
+  char *tmp = NULL;
+  bool foundAuth = FALSE;
+  bool foundAuthInt = FALSE;
+  struct SessionHandle *data=conn->data;
+  bool before = FALSE; /* got a nonce before */
+  struct oauthdata *d;
+
+  if(proxy) {
+    d = &data->state.proxyoauth;
+  }
+  else {
+    d = &data->state.oauth;
+  }
+
+  /* skip initial whitespaces */
+  while(*header && ISSPACE(*header))
+    header++;
+
+  if(checkprefix("OAuth", header)) {
+    header += strlen("OAuth");
+
+    /* clear off any former leftovers and init to defaults */
+    Curl_oauth_cleanup_one(d);
+
+    while(more) {
+      char value[MAX_VALUE_LENGTH];
+      char content[MAX_CONTENT_LENGTH];
+
+      while(*header && ISSPACE(*header))
+        header++;
+
+      /* extract a value=content pair */
+      if(!get_pair(header, value, content, &header)) {
+        if(Curl_raw_equal(value, "nonce")) {
+          d->nonce = strdup(content);
+          if(!d->nonce)
+            return CURLOAUTH_NOMEM;
+        }
+
+      }
+      else
+        break; /* we're done here */
+
+      /* pass all additional spaces here */
+      while(*header && ISSPACE(*header))
+        header++;
+      if(',' == *header)
+        /* allow the list to be comma-separated */
+        header++;
+    }
+
+    /* We got this header without a nonce, that's a bad Oauth line! */
+    if(!d->nonce)
+      return CURLOAUTH_BAD;
+  }
+  else
+    /* else not a oauth, get out */
+    return CURLOAUTH_NONE;
+
+  return CURLOAUTH_FINE;
+}
+
+CURLcode Curl_output_oauth(struct connectdata *conn,
+                           bool proxy,
+                           const unsigned char *request,
+                           const unsigned char *uripath)
+{
+  /* We have a OAuth setup for this, use it!  Now, to get all the details for
+     this sorted out, */
+  char *cnonce;
+  char *tmp = NULL;
+  struct timeval now;
+
+  char **allocuserpwd;
+  const char *userp;
+  const char *passwdp;
+  struct auth *authp;
+
+  struct SessionHandle *data = conn->data;
+  struct oauthdata *d;
+#ifdef CURL_DOES_CONVERSIONS
+  CURLcode rc;
+/* The CURL_OUTPUT_OAUTH_CONV macro below is for non-ASCII machines.
+   It converts oauth text to ASCII so the MD5 will be correct for
+   what ultimately goes over the network.
+*/
+#define CURL_OUTPUT_OAUTH_CONV(a, b) \
+  rc = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
+  if(rc != CURLE_OK) { \
+    free(b); \
+    return rc; \
+  }
+#else
+#define CURL_OUTPUT_OAUTH_CONV(a, b)
+#endif /* CURL_DOES_CONVERSIONS */
+
+  if(proxy) {
+    d = &data->state.proxyoauth;
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->proxyuser;
+    passwdp = conn->proxypasswd;
+    authp = &data->state.authproxy;
+  }
+  else {
+    d = &data->state.oauth;
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    passwdp = conn->passwd;
+    authp = &data->state.authhost;
+  }
+
+  if(*allocuserpwd) {
+    Curl_safefree(*allocuserpwd);
+    *allocuserpwd = NULL;
+  }
+
+  /* not set means empty */
+  if(!userp)
+    userp="";
+
+  if(!passwdp)
+    passwdp="";
+
+  if(!d->nonce) {
+    authp->done = FALSE;
+    return CURLE_OK;
+  }
+  authp->done = TRUE;
+
+  *allocuserpwd =
+    aprintf( "%sAuthorization: Oauth "
+             "username=\"\", "
+             "realm=\"\", "
+             "nonce=\"\", "
+             "uri=\"\", "
+             "response=\"\"",
+             proxy?"Proxy-":"");
+  if(!*allocuserpwd)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+void Curl_oauth_cleanup_one(struct oauthdata *d)
+{
+  if(d->nonce)
+    free(d->nonce);
+  d->nonce = NULL;
+
+}
+
+void Curl_oauth_cleanup(struct SessionHandle *data)
+{
+  Curl_oauth_cleanup_one(&data->state.oauth);
+  Curl_oauth_cleanup_one(&data->state.proxyoauth);
+}
+
+#endif
diff --git a/lib/http_oauth.h b/lib/http_oauth.h
new file mode 100644
index 0000000..ef73255
--- /dev/null
+++ b/lib/http_oauth.h
@@ -0,0 +1,53 @@
+#ifndef __HTTP_OAUTH_H
+#define __HTTP_OAUTH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+typedef enum {
+  CURLOAUTH_NONE, /* not a oauth */
+  CURLOAUTH_BAD,  /* a oauth, but one we don't like */
+  CURLOAUTH_BADALGO, /* unsupported algorithm requested */
+  CURLOAUTH_NOMEM,
+  CURLOAUTH_FINE, /* a oauth we act on */
+
+  CURLOAUTH_LAST  /* last entry in this enum, don't use */
+} CURLoauth;
+
+
+/* this is for oauth header input */
+CURLoauth Curl_input_oauth(struct connectdata *conn,
+                           bool proxy, const char *header);
+
+/* this is for creating oauth header output */
+CURLcode Curl_output_oauth(struct connectdata *conn,
+                           bool proxy,
+                           const unsigned char *request,
+                           const unsigned char *uripath);
+void Curl_oauth_cleanup_one(struct oauthdata *dig);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+void Curl_oauth_cleanup(struct SessionHandle *data);
+#else
+#define Curl_oauth_cleanup(x) do {} while(0)
+#endif
+
+#endif
diff --git a/lib/urldata.h b/lib/urldata.h
index efc56d7..f45fd9f 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -308,6 +308,11 @@ struct digestdata {
   int nc; /* nounce count */
 };
 
+/* Struct used for OAuth authentication */
+struct oauthdata {
+  char *nonce;
+};
+
 typedef enum {
   NTLMSTATE_NONE,
   NTLMSTATE_TYPE1,
@@ -1059,6 +1064,9 @@ struct UrlState {
   struct digestdata digest;      /* state data for host Digest auth */
   struct digestdata proxydigest; /* state data for proxy Digest auth */
 
+  struct oauthdata oauth;      /* state data for host Oauth auth */
+  struct oauthdata proxyoauth; /* state data for proxy Oauth auth */
+
 #ifdef HAVE_GSSAPI
   struct negotiatedata negotiate; /* state data for host Negotiate auth */
   struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
