aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/fetcher/fetcher.h6
-rw-r--r--src/libstrongswan/fetcher/fetcher_manager.c10
-rw-r--r--src/libstrongswan/plugins/curl/curl_fetcher.c9
-rw-r--r--src/scepclient/scep.c13
-rw-r--r--src/scepclient/scep.h5
-rw-r--r--src/scepclient/scepclient.c15
6 files changed, 51 insertions, 7 deletions
diff --git a/src/libstrongswan/fetcher/fetcher.h b/src/libstrongswan/fetcher/fetcher.h
index 58451aef2..890258c3c 100644
--- a/src/libstrongswan/fetcher/fetcher.h
+++ b/src/libstrongswan/fetcher/fetcher.h
@@ -90,6 +90,12 @@ enum fetcher_option_t {
FETCH_CALLBACK,
/**
+ * Source IP address to bind for a fetch.
+ * Additional argument is a host_t*, which may be NULL.
+ */
+ FETCH_SOURCEIP,
+
+ /**
* end of fetching options
*/
FETCH_END,
diff --git a/src/libstrongswan/fetcher/fetcher_manager.c b/src/libstrongswan/fetcher/fetcher_manager.c
index a638eef2f..21cd1aff4 100644
--- a/src/libstrongswan/fetcher/fetcher_manager.c
+++ b/src/libstrongswan/fetcher/fetcher_manager.c
@@ -73,6 +73,7 @@ METHOD(fetcher_manager_t, fetch, status_t,
fetcher_option_t opt;
fetcher_t *fetcher;
bool good = TRUE;
+ host_t *host;
va_list args;
/* check URL support of fetcher */
@@ -111,6 +112,14 @@ METHOD(fetcher_manager_t, fetch, status_t,
case FETCH_CALLBACK:
good = fetcher->set_option(fetcher, opt,
va_arg(args, fetcher_callback_t));
+ continue;
+ case FETCH_SOURCEIP:
+ host = va_arg(args, host_t*);
+ if (host && !host->is_anyaddr(host))
+ {
+ good = fetcher->set_option(fetcher, opt, host);
+ }
+ continue;
case FETCH_END:
break;
}
@@ -204,4 +213,3 @@ fetcher_manager_t *fetcher_manager_create()
return &this->public;
}
-
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c
index b49961a90..a8cca98da 100644
--- a/src/libstrongswan/plugins/curl/curl_fetcher.c
+++ b/src/libstrongswan/plugins/curl/curl_fetcher.c
@@ -177,6 +177,15 @@ METHOD(fetcher_t, set_option, bool,
this->cb = va_arg(args, fetcher_callback_t);
break;
}
+ case FETCH_SOURCEIP:
+ {
+ char buf[64];
+
+ snprintf(buf, sizeof(buf), "%H", va_arg(args, host_t*));
+ supported = curl_easy_setopt(this->curl, CURLOPT_INTERFACE,
+ buf) == CURLE_OK;
+ break;
+ }
default:
supported = FALSE;
break;
diff --git a/src/scepclient/scep.c b/src/scepclient/scep.c
index 3fdcd6c28..5bb29bbd8 100644
--- a/src/scepclient/scep.c
+++ b/src/scepclient/scep.c
@@ -339,15 +339,22 @@ static char* escape_http_request(chunk_t req)
* Send a SCEP request via HTTP and wait for a response
*/
bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
- bool http_get_request, u_int timeout, chunk_t *response)
+ bool http_get_request, u_int timeout, char *src,
+ chunk_t *response)
{
int len;
status_t status;
char *complete_url = NULL;
+ host_t *srcip = NULL;
/* initialize response */
*response = chunk_empty;
+ if (src)
+ {
+ srcip = host_create_from_string(src, 0);
+ }
+
DBG2(DBG_APP, "sending scep request to '%s'", url);
if (op == SCEP_PKI_OPERATION)
@@ -371,6 +378,7 @@ bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
FETCH_REQUEST_HEADER, "Pragma:",
FETCH_REQUEST_HEADER, "Host:",
FETCH_REQUEST_HEADER, "Accept:",
+ FETCH_SOURCEIP, srcip,
FETCH_END);
}
else /* HTTP_POST */
@@ -386,6 +394,7 @@ bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
FETCH_REQUEST_DATA, msg,
FETCH_REQUEST_TYPE, "",
FETCH_REQUEST_HEADER, "Expect:",
+ FETCH_SOURCEIP, srcip,
FETCH_END);
}
}
@@ -412,9 +421,11 @@ bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
status = lib->fetcher->fetch(lib->fetcher, complete_url, response,
FETCH_HTTP_VERSION_1_0,
FETCH_TIMEOUT, timeout,
+ FETCH_SOURCEIP, srcip,
FETCH_END);
}
+ DESTROY_IF(srcip);
free(complete_url);
return (status == SUCCESS);
}
diff --git a/src/scepclient/scep.h b/src/scepclient/scep.h
index ec8fa6515..4ef5eaf8e 100644
--- a/src/scepclient/scep.h
+++ b/src/scepclient/scep.h
@@ -78,8 +78,9 @@ chunk_t scep_build_request(chunk_t data, chunk_t transID, scep_msg_t msg,
certificate_t *enc_cert, encryption_algorithm_t enc_alg,
size_t key_size, certificate_t *signer_cert,
hash_algorithm_t digest_alg, private_key_t *private_key);
-bool scep_http_request(const char *url, chunk_t message, scep_op_t op,
- bool http_get_request, u_int timeout, chunk_t *response);
+bool scep_http_request(const char *url, chunk_t msg, scep_op_t op,
+ bool http_get_request, u_int timeout, char *src,
+ chunk_t *response);
err_t scep_parse_response(chunk_t response, chunk_t transID,
container_t **out, scep_attributes_t *attrs);
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index 26f210d12..17f4d7c5d 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -116,6 +116,9 @@ bool pkcs11_keep_state = FALSE;
/* by default HTTP fetch timeout is 30s */
static u_int http_timeout = 30;
+/* address to bind for HTTP fetches */
+static char* http_bind = NULL;
+
/* options read by optionsfrom */
options_t *options;
@@ -348,6 +351,7 @@ static void usage(const char *message)
" --optionsfrom (-+) <filename> reads additional options from given file\n"
" --force (-f) force existing file(s)\n"
" --httptimeout (-T) timeout for HTTP operations (default: 30s)\n"
+ " --bind (-b) source address to bind for HTTP operations\n"
"\n"
"Options for key generation (pkcs1):\n"
" --keylength (-k) <bits> key length for RSA key generation\n"
@@ -523,6 +527,7 @@ int main(int argc, char **argv)
{ "out", required_argument, NULL, 'o' },
{ "force", no_argument, NULL, 'f' },
{ "httptimeout", required_argument, NULL, 'T' },
+ { "bind", required_argument, NULL, 'b' },
{ "keylength", required_argument, NULL, 'k' },
{ "dn", required_argument, NULL, 'd' },
{ "days", required_argument, NULL, 'D' },
@@ -675,6 +680,10 @@ int main(int argc, char **argv)
}
continue;
+ case 'b': /* --bind */
+ http_bind = optarg;
+ continue;
+
case '+': /* --optionsfrom <filename> */
if (!options->from(options, optarg, &argc, &argv, optind))
{
@@ -953,7 +962,7 @@ int main(int argc, char **argv)
if (!scep_http_request(scep_url, chunk_create(ca_name, strlen(ca_name)),
SCEP_GET_CA_CERT, http_get_request,
- http_timeout, &scep_response))
+ http_timeout, http_bind, &scep_response))
{
exit_scepclient("did not receive a valid scep response");
}
@@ -1331,7 +1340,7 @@ int main(int argc, char **argv)
creds->add_cert(creds, TRUE, x509_ca_sig->get_ref(x509_ca_sig));
if (!scep_http_request(scep_url, pkcs7, SCEP_PKI_OPERATION,
- http_get_request, http_timeout, &scep_response))
+ http_get_request, http_timeout, http_bind, &scep_response))
{
exit_scepclient("did not receive a valid scep response");
}
@@ -1381,7 +1390,7 @@ int main(int argc, char **argv)
exit_scepclient("failed to build scep request");
}
if (!scep_http_request(scep_url, getCertInitial, SCEP_PKI_OPERATION,
- http_get_request, http_timeout, &scep_response))
+ http_get_request, http_timeout, http_bind, &scep_response))
{
exit_scepclient("did not receive a valid scep response");
}