added a BUILD_FROM_FD option, supporting credential parsing from stdin

This commit is contained in:
Martin Willi
2009-08-26 13:03:23 +02:00
parent 7c577c8ea2
commit df5c60bc5d
4 changed files with 48 additions and 1 deletions
+1
View File
@@ -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",
+3 -1
View File
@@ -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 */
@@ -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:
@@ -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;