/* This software is licensed under GPL-3, as shown in the file LICENSE Author: Linux Gruppe IRB Copyright: Linux Gruppe IRB, 2024 */ #include #include #include #include "client.h" static const char action_eid[] = "tcTokenURL=https://www.autentapp.de/AusweisAuskunft/WebServiceRequesterServlet?mode=xml"; static const char action_eid_ok[] = "http://www.bsi.bund.de/ecard/api/1.1/resultmajor#ok"; char errbuf[CURL_ERROR_SIZE]; int port; static CURLcode client_action(CURL *curl, const char *action) { char url[1024]; snprintf(url, (sizeof url) - 1, "http://127.0.0.1:%d/eID-Client?%s", port, action); curl_easy_setopt(curl, CURLOPT_URL, url); return curl_easy_perform(curl); } static size_t read_eidData(char *data, size_t size, size_t nmemb, void *clientp) { struct memory *mem = (struct memory *) clientp; size_t realsize = size * nmemb; char *ptr = realloc(mem->response, mem->size + realsize + 1); if (!ptr) return 0; /* out of memory! */ mem->response = ptr; memcpy(&(mem->response[mem->size]), data, realsize); mem->size += realsize; mem->response[mem->size] = 0; return realsize; } char *eidResponse(CURL *curl) { struct memory eidData = {0}; char *url = NULL; long code; int r; curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &errbuf); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0); #define MAX_TRIES 10 if (port == 41325) { for (int tries = 1; tries <= MAX_TRIES; tries++) { if ((r = client_action(curl, action_eid)) == CURLE_OK) break; sleep(1); } } else r = client_action(curl, action_eid); if (r != CURLE_OK) return NULL; while ((curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code) == CURLE_OK) && (code >= 300) && (code < 400) && (curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &url) == CURLE_OK) && url) { /* follow redirects manually to make sure that we get authenticated * data exclusively from https://www.autentapp.de, which we use as * trusted source for comparison against the reference data */ if (strstr(url, "https://www.autentapp.de")) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, read_eidData); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) &eidData); } curl_easy_setopt(curl, CURLOPT_URL, url); if ((r = curl_easy_perform(curl) != CURLE_OK)) break; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); } if ((r == CURLE_OK) && (strstr(eidData.response, action_eid_ok) != NULL)) return eidData.response; else return NULL; }