summaryrefslogtreecommitdiff
path: root/imap/src/c-client/oauth2_aux.c
diff options
context:
space:
mode:
Diffstat (limited to 'imap/src/c-client/oauth2_aux.c')
-rw-r--r--imap/src/c-client/oauth2_aux.c132
1 files changed, 111 insertions, 21 deletions
diff --git a/imap/src/c-client/oauth2_aux.c b/imap/src/c-client/oauth2_aux.c
index a23f7c28..88ee52a6 100644
--- a/imap/src/c-client/oauth2_aux.c
+++ b/imap/src/c-client/oauth2_aux.c
@@ -53,6 +53,7 @@ char *oauth2_generate_state(void)
JSON_S *oauth2_json_reply(OAUTH2_SERVER_METHOD_S, OAUTH2_S *, int *);
+char *xoauth2_server(char *, char *);
#define LOAD_HTTP_PARAMS(X, Y) { \
int i; \
@@ -64,20 +65,60 @@ JSON_S *oauth2_json_reply(OAUTH2_SERVER_METHOD_S, OAUTH2_S *, int *);
(Y)[i].name = (Y)[i].value = NULL; \
}
+char *xoauth2_server(char *server, char *tenant)
+{
+ char *rv = NULL;
+ char *s;
+
+ if (server == NULL) return NULL;
+
+ s = cpystr(server);
+ if(tenant){
+ char *t = s, *u;
+ int i;
+ for(i = 0; t != NULL; i++){
+ t = strchr(t, '\001');
+ if(t != NULL) t++;
+ }
+ rv = fs_get((strlen(s) + i*(strlen(tenant)-1) + 1)*sizeof(char));
+ *rv = '\0';
+ for(u = t = s; t != NULL; i++){
+ t = strchr(t, '\001');
+ if (t != NULL) *t = '\0';
+ strcat(rv, u);
+ if(t != NULL){
+ strcat(rv, tenant);
+ *t++ = '\001';
+ }
+ u = t;
+ }
+
+ }
+ else
+ rv = cpystr(server);
+
+ return rv;
+}
+
JSON_S *oauth2_json_reply(OAUTH2_SERVER_METHOD_S RefreshMethod, OAUTH2_S *oauth2, int *status)
{
JSON_S *json = NULL;
HTTP_PARAM_S params[OAUTH2_PARAM_NUMBER];
unsigned char *s;
+ char *server = NULL;
LOAD_HTTP_PARAMS(RefreshMethod, params);
*status = 0;
+ server = xoauth2_server(RefreshMethod.urlserver, oauth2->param[OA2_Tenant].value);
if(strcmp(RefreshMethod.name, "POST") == 0
- && ((s = http_post_param(RefreshMethod.urlserver, params, status)) != NULL)){
+ && ((s = http_post_param(server, params, status)) != NULL)){
unsigned char *u = s;
json = json_parse(&u);
fs_give((void **) &s);
}
+ if(server)
+ fs_give((void **) &server);
+
return json;
}
@@ -92,11 +133,16 @@ mm_login_oauth2_c_client_method (NETMBX *mb, char *user, char *method,
if(oauth2->param[OA2_Id].value == NULL
|| (oauth2->require_secret && oauth2->param[OA2_Secret].value == NULL)){
+ XOAUTH2_INFO_S *x;
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(ogci && (x = (*ogci)(oauth2->name, user)) != NULL){
+ oauth2->param[OA2_Id].value = cpystr(x->client_id);
+ oauth2->param[OA2_Secret].value = x->client_secret ? cpystr(x->client_secret) : NULL;
+ oauth2->param[OA2_Tenant].value = x->tenant ? cpystr(x->tenant) : NULL;
+ free_xoauth2_info(&x);
+ }
}
if(oauth2->param[OA2_Id].value == NULL
@@ -157,24 +203,34 @@ mm_login_oauth2_c_client_method (NETMBX *mb, char *user, char *method,
/* else check if we have a refresh token, and in that case use it */
if(oauth2->param[OA2_RefreshToken].value){
-
json = oauth2_json_reply(oauth2->server_mthd[OA2_GetAccessTokenFromRefreshToken], oauth2, &status);
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);
+ switch(status){
+ case HTTP_UNAUTHORIZED:
+ mm_log("Client not authorized (wrong client-id?)", ERROR);
+ break;
+ case HTTP_OK: jx = json_body_value(json, "access_token");
+ if(jx && jx->jtype == JString)
+ oauth2->access_token = cpystr((char *) jx->value);
- if((jx = json_body_value(json, "expires_in")) != NULL)
- switch(jx->jtype){
- case JString: oauth2->expiration = time(0) + atol((char *) jx->value);
- break;
- case JLong : oauth2->expiration = time(0) + *(long *) jx->value;
- break;
- }
+ if((jx = json_body_value(json, "expires_in")) != NULL)
+ switch(jx->jtype){
+ case JString: oauth2->expiration = time(0) + atol((char *) jx->value);
+ break;
+ case JLong : oauth2->expiration = time(0) + *(long *) jx->value;
+ break;
+ }
+ break;
+ default : { char tmp[100];
+ sprintf(tmp, "Oauth2 client Received Code %d", status);
+ mm_log (tmp, ERROR);
+ }
+ break;
+ }
json_free(&json);
}
return;
@@ -190,12 +246,15 @@ mm_login_oauth2_c_client_method (NETMBX *mb, char *user, char *method,
LOAD_HTTP_PARAMS(RefreshMethod, params);
if(strcmp(RefreshMethod.name, "GET") == 0){
- char *url = http_get_param_url(RefreshMethod.urlserver, params);
+ char *server = xoauth2_server(RefreshMethod.urlserver, oauth2->param[OA2_Tenant].value);
+ char *url = http_get_param_url(server, 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(server) fs_give((void **) &server);
}
if(oauth2->param[OA2_Code].value){
@@ -230,7 +289,7 @@ mm_login_oauth2_c_client_method (NETMBX *mb, char *user, char *method,
case HTTP_BAD : break;
default : { char tmp[100];
- sprintf(tmp, "Oauth Client Received Code %d", status);
+ sprintf(tmp, "Oauth2 Client Received Code %d", status);
fatal (tmp);
}
}
@@ -240,8 +299,6 @@ mm_login_oauth2_c_client_method (NETMBX *mb, char *user, char *method,
}
return;
}
-
- /* Else, does this server use the /devicecode method? */
}
void oauth2deviceinfo_get_accesscode(void *inp, void *outp)
@@ -304,9 +361,9 @@ void oauth2deviceinfo_get_accesscode(void *inp, void *outp)
break;
default : { char tmp[100];
- sprintf(tmp, "Oauth device Received Code %d", status);
- fatal (tmp);
- }
+ sprintf(tmp, "Oauth device Received Code %d", status);
+ mm_log (tmp, ERROR);
+ }
}
json_free(&json);
@@ -314,3 +371,36 @@ void oauth2deviceinfo_get_accesscode(void *inp, void *outp)
*(int *)outp = rv;
}
+
+XOAUTH2_INFO_S *new_xoauth2_info(void)
+{
+ XOAUTH2_INFO_S *rv = fs_get(sizeof(XOAUTH2_INFO_S));
+ memset((void *) rv, 0, sizeof(XOAUTH2_INFO_S));
+ return rv;
+}
+
+void free_xoauth2_info(XOAUTH2_INFO_S **xp)
+{
+ if(xp == NULL || *xp == NULL) return;
+
+ if((*xp)->name) fs_give((void **) &(*xp)->name);
+ if((*xp)->client_id) fs_give((void **) &(*xp)->client_id);
+ if((*xp)->client_secret) fs_give((void **) &(*xp)->client_secret);
+ if((*xp)->tenant) fs_give((void **) &(*xp)->tenant);
+ if((*xp)->users) fs_give((void **) &(*xp)->users);
+ fs_give((void **) xp);
+}
+
+XOAUTH2_INFO_S *copy_xoauth2_info(XOAUTH2_INFO_S *x)
+{
+ XOAUTH2_INFO_S *y;
+
+ if(x == NULL) return NULL;
+ y = new_xoauth2_info();
+ if(x->name) y->name = cpystr(x->name);
+ if(x->client_id) y->client_id = cpystr(x->client_id);
+ if(x->client_secret) y->client_secret = cpystr(x->client_secret);
+ if(x->tenant) y->tenant = cpystr(x->tenant);
+ if(x->users) y->users = cpystr(x->users);
+ return y;
+}