diff options
Diffstat (limited to 'imap/src/c-client/oauth2_aux.c')
-rw-r--r-- | imap/src/c-client/oauth2_aux.c | 132 |
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; +} |