pam-eid/client.c

99 lines
2.5 KiB
C
Raw Permalink Normal View History

2024-10-29 13:39:15 +01:00
/*
This software is licensed under GPL-3, as shown in the file LICENSE
Author: Linux Gruppe IRB
Copyright: Linux Gruppe IRB, 2024
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "client.h"
static const char action_eid[] = "tcTokenURL=https://www.autentapp.de/AusweisAuskunft/WebServiceRequesterServlet?mode=xml";
static const char action_eid_ok[] = "<ns2:ResultMajor>http://www.bsi.bund.de/ecard/api/1.1/resultmajor#ok</ns2:ResultMajor>";
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;
}