summaryrefslogtreecommitdiff
path: root/imap/src/c-client/auth_bea.c
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2020-06-12 02:21:59 -0600
committerEduardo Chappa <chappa@washington.edu>2020-06-12 02:21:59 -0600
commit6c120b9e3730f997af56fbbe19229915b6380b2d (patch)
tree2acef9df0ffa1991a90cc1ded54400d1e0c1b35f /imap/src/c-client/auth_bea.c
parentd600da07926e1ec3243c2a96cd988c61d6a97614 (diff)
downloadalpine-6c120b9e3730f997af56fbbe19229915b6380b2d.tar.xz
* Initial implementation of XOAUTH2 authentication support for Outlook.
Based on documentation suggested by Andrew C Aitchison.
Diffstat (limited to 'imap/src/c-client/auth_bea.c')
-rw-r--r--imap/src/c-client/auth_bea.c181
1 files changed, 2 insertions, 179 deletions
diff --git a/imap/src/c-client/auth_bea.c b/imap/src/c-client/auth_bea.c
index 6079fb7b..bf5c9c1e 100644
--- a/imap/src/c-client/auth_bea.c
+++ b/imap/src/c-client/auth_bea.c
@@ -11,12 +11,11 @@
* ========================================================================
*/
+#include "oauth2_aux.h"
+
long auth_oauthbearer_client (authchallenge_t challenger,authrespond_t responder, char *base,
char *service,NETMBX *mb,void *stream, unsigned long port,
unsigned long *trial,char *user);
-#ifndef HTTP_OAUTH2_INCLUDED
-void mm_login_oauth2_c_client_method (NETMBX *, char *, char *, OAUTH2_S *, unsigned long, int *);
-#endif /* HTTP_OAUTH2_INCLUDED */
AUTHENTICATOR auth_bea = {
AU_HIDE | AU_SINGLE, /* hidden, single trip */
@@ -34,38 +33,6 @@ AUTHENTICATOR auth_bea = {
#define BEARER_HOST "host="
#define BEARER_PORT "port="
-#ifndef OAUTH2_GENERATE_STATE
-#define OAUTH2_GENERATE_STATE
-char *oauth2_generate_state(void);
-
-/* we generate something like a guid, but not care about
- * anything, but that it is really random.
- */
-char *oauth2_generate_state(void)
-{
- char rv[37];
- int i;
-
- rv[0] = '\0';
- for(i = 0; i < 4; i++)
- sprintf(rv + strlen(rv), "%x", (unsigned int) (random() % 256));
- sprintf(rv + strlen(rv), "%c", '-');
- for(i = 0; i < 2; i++)
- sprintf(rv + strlen(rv), "%x", (unsigned int) (random() % 256));
- sprintf(rv + strlen(rv), "%c", '-');
- for(i = 0; i < 2; i++)
- sprintf(rv + strlen(rv), "%x", (unsigned int) (random() % 256));
- sprintf(rv + strlen(rv), "%c", '-');
- for(i = 0; i < 2; i++)
- sprintf(rv + strlen(rv), "%x", (unsigned int) (random() % 256));
- sprintf(rv + strlen(rv), "%c", '-');
- for(i = 0; i < 6; i++)
- sprintf(rv + strlen(rv), "%x", (unsigned int) (random() % 256));
- rv[36] = '\0';
- return cpystr(rv);
-}
-#endif /* OAUTH2_GENERATE_STATE */
-
/* Client authenticator
* Accepts: challenger function
* responder function
@@ -196,147 +163,3 @@ long auth_oauthbearer_client (authchallenge_t challenger,authrespond_t responder
*trial = 65535; /* don't retry if bad protocol */
return ret;
}
-
-#ifndef HTTP_OAUTH2_INCLUDED
-#define HTTP_OAUTH2_INCLUDED
-/*
- * The code above is enough to implement OAUTHBEARER, all one needs is the username
- * and access token and give it to the function above. However, normal users cannot
- * be expected to get the access token, so we ask the client to help with getting
- * the access token, refresh token and expire values, so the code below is written
- * to help with that.
- */
-
-#include "http.h"
-#include "json.h"
-
-void
-mm_login_oauth2_c_client_method (NETMBX *mb, char *user, char *method,
- OAUTH2_S *oauth2, unsigned long trial, int *tryanother)
-{
- int i;
- HTTP_PARAM_S params[OAUTH2_PARAM_NUMBER];
- OAUTH2_SERVER_METHOD_S RefreshMethod;
- unsigned char *s = NULL;
- JSON_S *json = NULL;
- int status = 0;
-
- if(oauth2->param[OA2_Id].value == NULL || oauth2->param[OA2_Secret].value == NULL){
- oauth2clientinfo_t ogci =
- (oauth2clientinfo_t) mail_parameters (NIL, GET_OA2CLIENTINFO, NIL);
-
- if(ogci) (*ogci)(oauth2->name, &oauth2->param[OA2_Id].value,
- &oauth2->param[OA2_Secret].value);
- }
-
- if(oauth2->param[OA2_Id].value == NULL || oauth2->param[OA2_Secret].value == NULL)
- return;
-
- /* first check if we have a refresh token, and in that case use it */
- if(oauth2->param[OA2_RefreshToken].value){
-
- RefreshMethod = oauth2->server_mthd[OA2_GetAccessTokenFromRefreshToken];
- for(i = 0; RefreshMethod.params[i] != OA2_End; i++){
- OA2_type j = RefreshMethod.params[i];
- params[i].name = oauth2->param[j].name;
- params[i].value = oauth2->param[j].value;
- }
- params[i].name = params[i].value = NULL;
-
- if(strcmp(RefreshMethod.name, "POST") == 0)
- s = http_post_param(RefreshMethod.urlserver, params, &status);
- else if(strcmp(RefreshMethod.name, "POST2") == 0)
- s = http_post_param2(RefreshMethod.urlserver, params, &status);
-
- if(status != 200 && s)
- fs_give((void **) &s); /* at this moment ignore the reply text */
-
- if(s){
- unsigned char *u = s;
- json = json_parse(&u);
- fs_give((void **) &s);
- }
-
- if(json != NULL){
- JSON_X *jx;
-
- jx = json_body_value(json, "access_token");
- if(jx && jx->jtype == JString)
- oauth2->access_token = cpystr((char *) jx->value);
-
- jx = json_body_value(json, "expires_in");
- if(jx && jx->jtype == JString)
- oauth2->expiration = time(0) + atol((char *) jx->value);
-
- json_free(&json);
- }
- return;
- }
- /*
- * else, we do not have a refresh token, nor an access token.
- * We need to start the process to get an access code. We use this
- * to get an access token and refresh token.
- */
- {
- RefreshMethod = oauth2->server_mthd[OA2_GetAccessCode];
- for(i = 0; RefreshMethod.params[i] != OA2_End; i++){
- OA2_type j = RefreshMethod.params[i];
- params[i].name = oauth2->param[j].name;
- params[i].value = oauth2->param[j].value;
- }
- params[i].name = params[i].value = NULL;
-
- if(strcmp(RefreshMethod.name, "GET") == 0){
- unsigned char *url = http_get_param_url(RefreshMethod.urlserver, params);
- oauth2getaccesscode_t ogac =
- (oauth2getaccesscode_t) mail_parameters (NIL, GET_OA2CLIENTGETACCESSCODE, NIL);
-
- if(ogac)
- oauth2->param[OA2_Code].value = (*ogac)(url, method, oauth2, tryanother);
- }
-
- if(oauth2->param[OA2_Code].value){
- RefreshMethod = oauth2->server_mthd[OA2_GetAccessTokenFromAccessCode];
- for(i = 0; RefreshMethod.params[i] != OA2_End; i++){
- OA2_type j = RefreshMethod.params[i];
- params[i].name = oauth2->param[j].name;
- params[i].value = oauth2->param[j].value;
- }
- params[i].name = params[i].value = NULL;
-
- if(strcmp(RefreshMethod.name, "POST") == 0)
- s = http_post_param(RefreshMethod.urlserver, params, &status);
- else if(strcmp(RefreshMethod.name, "POST2") == 0)
- s = http_post_param2(RefreshMethod.urlserver, params, &status);
-
- if(status != 200 && s)
- fs_give((void **) &s); /* at this moment ignore the error */
-
- if(s){
- unsigned char *u = s;
- json = json_parse(&u);
- fs_give((void **) &s);
- }
-
- if(json != NULL){
- JSON_X *jx;
-
- jx = json_body_value(json, "refresh_token");
- if(jx && jx->jtype == JString)
- oauth2->param[OA2_RefreshToken].value = cpystr((char *) jx->value);
-
- jx = json_body_value(json, "access_token");
- if(jx && jx->jtype == JString)
- oauth2->access_token = cpystr((char *) jx->value);
-
- jx = json_body_value(json, "expires_in");
- if(jx && jx->jtype == JString)
- oauth2->expiration = time(0) + atol((char *) jx->value);
-
- json_free(&json);
- }
- }
- return;
- }
-}
-#endif /* HTTP_OAUTH2_INCLUDED */