scepclient: support a --bind option to fetch from a specific source IP
authorMartin Willi <martin@revosec.ch>
Wed, 15 May 2013 14:59:34 +0000 (16:59 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 11 Jun 2013 13:54:26 +0000 (15:54 +0200)
src/scepclient/scep.c
src/scepclient/scep.h
src/scepclient/scepclient.c

index 3fdcd6c..5bb29bb 100644 (file)
@@ -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);
 }
index ec8fa65..4ef5eaf 100644 (file)
@@ -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);
 
index 26f210d..17f4d7c 100644 (file)
@@ -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");
                        }