From df5c60bc5d4744c4dc62188a416c22b802fee6f1 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 26 Aug 2009 13:03:23 +0200 Subject: [PATCH] added a BUILD_FROM_FD option, supporting credential parsing from stdin --- src/libstrongswan/credentials/builder.c | 1 + src/libstrongswan/credentials/builder.h | 4 +- .../credentials/credential_factory.c | 1 + src/libstrongswan/plugins/pem/pem_builder.c | 43 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c index c21236883..601ae94b6 100644 --- a/src/libstrongswan/credentials/builder.c +++ b/src/libstrongswan/credentials/builder.c @@ -17,6 +17,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END, "BUILD_FROM_FILE", + "BUILD_FROM_FD", "BUILD_AGENT_SOCKET", "BUILD_BLOB_ASN1_DER", "BUILD_BLOB_PEM", diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h index ed3862c5a..678a84429 100644 --- a/src/libstrongswan/credentials/builder.h +++ b/src/libstrongswan/credentials/builder.h @@ -38,8 +38,10 @@ typedef builder_t* (*builder_constructor_t)(int subtype); * Parts to build credentials from. */ enum builder_part_t { - /** path to a file containing an ASN.1 blob, char* */ + /** path to a file encoded in any format, char* */ BUILD_FROM_FILE, + /** file descriptor to read data, encoded in any format, int */ + BUILD_FROM_FD, /** unix socket of a ssh/pgp agent, char* */ BUILD_AGENT_SOCKET, /** DER encoded ASN.1 blob, chunk_t */ diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c index 776cde2eb..e99f0f25c 100644 --- a/src/libstrongswan/credentials/credential_factory.c +++ b/src/libstrongswan/credentials/credential_factory.c @@ -183,6 +183,7 @@ static void* create(private_credential_factory_t *this, credential_type_t type, builder->add(builder, part, va_arg(args, x509_flag_t)); continue; case BUILD_KEY_SIZE: + case BUILD_FROM_FD: builder->add(builder, part, va_arg(args, u_int)); continue; case BUILD_NOT_BEFORE_TIME: diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index 72cc8a301..ed9b2304c 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -50,6 +50,8 @@ struct private_builder_t { int subtype; /** path to file, if we are reading from a file */ char *file; + /** file description, if we are reading from a fd */ + int fd; /** PEM encoding of the credential */ chunk_t pem; /** PEM decryption passphrase, if given */ @@ -438,6 +440,37 @@ static void *build_from_file(private_builder_t *this, char *file) return cred; } +/** + * build the credential from a file + */ +static void *build_from_fd(private_builder_t *this, int fd) +{ + char buf[8096]; + char *pos = buf; + ssize_t len, total = 0; + + while (TRUE) + { + len = read(fd, pos, buf + sizeof(buf) - pos); + if (len < 0) + { + DBG1("reading from file descriptor failed: %s", strerror(errno)); + return NULL; + } + if (len == 0) + { + break; + } + total += len; + if (total == sizeof(buf)) + { + DBG1("buffer too small to read from file descriptor"); + return NULL; + } + } + return build_from_blob(this, chunk_create(buf, total)); +} + /** * Implementation of builder_t.build */ @@ -453,6 +486,10 @@ static void *build(private_builder_t *this) { cred = build_from_file(this, this->file); } + else if (this->fd != -1) + { + cred = build_from_fd(this, this->fd); + } free(this); return cred; } @@ -483,6 +520,11 @@ static void add(private_builder_t *this, builder_part_t part, ...) this->file = va_arg(args, char*); va_end(args); break; + case BUILD_FROM_FD: + va_start(args, part); + this->fd = va_arg(args, int); + va_end(args); + break; case BUILD_BLOB_PEM: va_start(args, part); this->pem = va_arg(args, chunk_t); @@ -528,6 +570,7 @@ static builder_t *pem_builder(credential_type_t type, int subtype) this->type = type; this->subtype = subtype; this->file = NULL; + this->fd = -1; this->pem = chunk_empty; this->passphrase = chunk_empty; this->cb = NULL;