/* * Functionalities related to OpenId Connect based authentication */ #include "putty.h" #include "oidc-agent/api.h" #include <stdio.h> #include <curl/curl.h> #include "cJSON.h" accesstoken_response *get_accesstoken(char *oidc_configuration) { accesstoken_response *pq = snew(accesstoken_response); pq->accesstoken = getAccessToken3(oidc_configuration, 60, NULL, "putty-ssh-client", NULL); return pq; } struct memory { char *response; size_t size; }; static size_t cb(void *data, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct memory *mem = (struct memory *)userp; char *ptr = realloc(mem->response, mem->size + realsize + 1); if(ptr == NULL) return 0; mem->response = ptr; memcpy(&(mem->response[mem->size]), data, realsize); mem->size += realsize; mem->response[mem->size] = 0; return realsize; } struct memory chunk; deployed_user *deploy_user(char *hostname, char *oidc_configuration, char *oidc_motley_cue_host, int oidc_motley_cue_port) { deployed_user *pq = snew(deployed_user); // Sanity check for oidc configuration if (oidc_configuration == NULL) { pq->deployed = false; return pq; } CURL *curl; CURLcode res; cJSON *ssh_user; curl = curl_easy_init(); if(curl) { char endpoint[1028]; if (oidc_motley_cue_host == NULL) { sprintf(endpoint, "%s/user/deploy", hostname); } else { sprintf(endpoint, "%s/user/deploy", oidc_motley_cue_host); } int port; if (oidc_motley_cue_port != 0) { port = oidc_motley_cue_port; } else { port = 8080; } curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); curl_easy_setopt(curl, CURLOPT_URL, endpoint); curl_easy_setopt(curl, CURLOPT_PORT, port); curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2); struct curl_slist *headers = NULL; char authorization[1028]; accesstoken_response *conf = get_accesstoken(oidc_configuration); sprintf(authorization, "Authorization: Bearer %s", conf->accesstoken); sfree(conf); headers = curl_slist_append(headers, authorization); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); res = curl_easy_perform(curl); sfree(authorization); sfree(headers); long response_code; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); if((res != CURLE_OK) || (response_code != 200)) { pq->deployed = false; curl_easy_cleanup(curl); return pq; } curl_easy_cleanup(curl); } cJSON *json = cJSON_Parse(chunk.response); cJSON *state = cJSON_GetObjectItem(json, "state"); if (strcmp(state->valuestring, "deployed") != 0) { pq->deployed = false; return pq; } cJSON *credentials = cJSON_GetObjectItem(json, "credentials"); ssh_user = cJSON_GetObjectItem(credentials, "ssh_user"); pq->username = strdup(ssh_user->valuestring); pq->deployed = true; return pq; } oidc_configurations *get_loaded_oidc_configurations() { char *configs_str = getLoadedAccountsList(); if (configs_str != NULL) { cJSON *json = cJSON_Parse(configs_str); oidc_configurations *ocs = new_oidc_configurations(); for (int i = 0; i < cJSON_GetArraySize(json); i++) { add_oidc_configuration(ocs, cJSON_GetArrayItem(json, i)->valuestring, i); } sfree(configs_str); return ocs; } else { return NULL; } }