41static size_t curl_callback_write(
void *ptr,
size_t size,
size_t nmemb,
46 if (data->size +
size * nmemb < data->
size ||
47 data->size +
size * nmemb > data->max_size) {
51 memcpy(data->data + data->size, ptr,
size * nmemb);
52 data->size +=
size * nmemb;
57static void backend_set_verbosity(
uint8_t verbosity, FILE *output) {
62static yh_rc backend_init(
uint8_t verbosity, FILE *output) {
65 backend_set_verbosity(verbosity, output);
67 rc = curl_global_init(
77static yh_backend *backend_create() {
return curl_easy_init(); }
86 char curl_error[CURL_ERROR_SIZE] = {0};
91 curl_easy_setopt(connector->
connection, CURLOPT_CONNECTTIMEOUT, timeout);
92#ifdef CURLOPT_TCP_KEEPALIVE
93 curl_easy_setopt(connector->
connection, CURLOPT_TCP_KEEPALIVE, 1);
95 curl_easy_setopt(connector->
connection, CURLOPT_FAILONERROR, 1);
96 curl_easy_setopt(connector->
connection, CURLOPT_USERAGENT,
97 "YubiHSM curl/" VERSION);
99 curl_easy_setopt(connector->
connection, CURLOPT_WRITEFUNCTION,
100 curl_callback_write);
102 curl_easy_setopt(connector->
connection, CURLOPT_ERRORBUFFER, curl_error);
105 data.curl_data.data = (
uint8_t *) data.scratch;
106 data.curl_data.size = 0;
107 data.curl_data.max_size =
sizeof(data.scratch) - 1;
108 curl_easy_setopt(connector->
connection, CURLOPT_WRITEDATA, &data.curl_data);
111 if (
rc != CURLE_OK) {
112 if (strlen(curl_error) > 0) {
113 DBG_ERR(
"Failure when connecting: '%s'", curl_error);
115 DBG_ERR(
"Failure when connecting: '%s'", curl_easy_strerror(
rc));
120 if (strlen(data.scratch) != data.curl_data.size) {
121 DBG_ERR(
"Amount of data received does not match scratch buffer. Expected "
123 strlen(data.scratch), data.curl_data.size);
129 DBG_INFO(
"Found working connector");
136static void backend_disconnect(
yh_backend *connection) {
137 curl_easy_cleanup(connection);
145 struct curl_slist *
headers = NULL;
146 char curl_error[CURL_ERROR_SIZE] = {0};
149 curl_slist_append(
headers,
"Content-Type: application/octet-stream");
151 curl_easy_setopt(connection, CURLOPT_HTTPHEADER,
headers);
152 curl_easy_setopt(connection, CURLOPT_POSTFIELDS, (
void *) msg->
raw);
153 curl_easy_setopt(connection, CURLOPT_POSTFIELDSIZE, trf_len);
155 curl_easy_setopt(connection, CURLOPT_WRITEDATA, &data);
156 curl_easy_setopt(connection, CURLOPT_ERRORBUFFER, curl_error);
159 msg->
st.len = htons(msg->
st.len);
162 rc = curl_easy_perform(connection);
164 if (
rc != CURLE_OK) {
169 DBG_ERR(
"Not enough data received: %d", data.size);
173 response->st.len = ntohs(response->st.len);
175 if (response->st.len != data.size - 3) {
176 DBG_ERR(
"Wrong length received, %d vs %d", response->st.len, data.size);
184 if (strlen(curl_error) > 0) {
185 DBG_ERR(
"Curl perform failed: '%s'", curl_error);
187 DBG_ERR(
"Curl perform failed: '%s'", curl_easy_strerror(
rc));
191 msg->
st.len = ntohs(msg->
st.len);
194 response->st.len = 0;
199static void backend_cleanup(
void) {
215 optname =
"CURLOPT_CAINFO";
219 optname =
"CURLOPT_PROXY";
222 DBG_ERR(
"%d is an unknown option", opt);
225 CURLcode
rc = curl_easy_setopt(connection,
option, (
char *) val);
226 if (
rc == CURLE_OK) {
227 DBG_INFO(
"Successfully set %s.", optname);
230 DBG_ERR(
"Failed to set %s (%d): %s", optname,
rc, curl_easy_strerror(
rc));
void YH_INTERNAL parse_status_data(char *data, yh_connector *connector)
yh_rc(* backend_init)(uint8_t verbosity, FILE *output)
void(* backend_set_verbosity)(uint8_t verbosity, FILE *output)
void(* backend_disconnect)(yh_backend *connection)
yh_rc(* backend_send_msg)(yh_backend *connection, Msg *msg, Msg *response)
yh_rc(* backend_option)(yh_backend *connection, yh_connector_option opt, const void *val)
yh_backend *(* backend_create)(void)
void(* backend_cleanup)(void)
yh_rc(* backend_connect)(yh_connector *connector, int timeout)
uint8_t raw[3+SCP_MSG_BUF_SIZE]
@ YH_CONNECTOR_PROXY_SERVER
@ YHR_GENERIC_ERROR
Return value when encountering an unknown error.
@ YHR_SUCCESS
Returned value when function was successful.
@ YHR_INVALID_PARAMETERS
Returned value when an argument to a function is invalid.
@ YHR_CONNECTOR_NOT_FOUND
Returned value when failing to find a suitable connector.
@ YHR_CONNECTOR_ERROR
Return value when connector operation failed.
@ YHR_CONNECTION_ERROR
Returned value when a connection error was encountered.
FILE YH_INTERNAL * _yh_output
struct backend_functions * backend_functions(void)
uint8_t YH_INTERNAL _yh_verbosity
memset(pInfo->slotDescription, ' ', 64)
memcpy((char *) pInfo->slotDescription, s, l)