diff options
Diffstat (limited to 'src/charon/lib')
-rw-r--r-- | src/charon/lib/asn1/asn1.c | 55 | ||||
-rwxr-xr-x | src/charon/lib/asn1/pem.c | 205 | ||||
-rwxr-xr-x | src/charon/lib/asn1/pem.h | 8 | ||||
-rw-r--r-- | src/charon/lib/asn1/ttodata.h | 2 | ||||
-rw-r--r-- | src/charon/lib/crypto/rsa/rsa_private_key.c | 39 | ||||
-rwxr-xr-x | src/charon/lib/crypto/x509.c | 43 | ||||
-rw-r--r-- | src/charon/lib/types.h | 5 | ||||
-rw-r--r-- | src/charon/lib/utils/Makefile.utils | 6 | ||||
-rw-r--r-- | src/charon/lib/utils/lexparser.c | 135 | ||||
-rw-r--r-- | src/charon/lib/utils/lexparser.h | 57 | ||||
-rw-r--r-- | src/charon/lib/utils/logger.c | 6 |
11 files changed, 370 insertions, 191 deletions
diff --git a/src/charon/lib/asn1/asn1.c b/src/charon/lib/asn1/asn1.c index c847461b6..e894999fb 100644 --- a/src/charon/lib/asn1/asn1.c +++ b/src/charon/lib/asn1/asn1.c @@ -21,8 +21,6 @@ #include <utils/logger_manager.h> -static logger_t *logger; - /* Names of the months */ static const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -87,7 +85,18 @@ static const asn1Object_t algorithmIdentifierObjects[] = { #define ALGORITHM_ID_PARAMETERS 2 #define ALGORITHM_ID_ROOF 3 -/* +static logger_t *logger = NULL; + +/** + * initializes the ASN.1 logger + */ +static void asn1_init_logger() +{ + if (logger == NULL) + logger = logger_manager->get_logger(logger_manager, ASN1); +} + +/** * return the ASN.1 encoded algorithm identifier */ chunk_t asn1_algorithmIdentifier(int oid) @@ -109,7 +118,7 @@ chunk_t asn1_algorithmIdentifier(int oid) } } -/* +/** * If the oid is listed in the oid_names table then the corresponding * position in the oid_names table is returned otherwise -1 is returned */ @@ -141,7 +150,7 @@ int known_oid(chunk_t object) return -1; } -/* +/** * Decodes the length in bytes of an ASN.1 object */ u_int asn1_length(chunk_t *blob) @@ -188,7 +197,7 @@ u_int asn1_length(chunk_t *blob) return len; } -/* +/** * determines if a character string is of type ASN.1 printableString */ bool is_printablestring(chunk_t str) @@ -205,9 +214,9 @@ bool is_printablestring(chunk_t str) return TRUE; } -/* +/** * Display a date either in local or UTC time - * TODO: Does not seem to be thread save + * TODO: Does not seem to be thread safe */ char* timetoa(const time_t *time, bool utc) { @@ -225,7 +234,7 @@ char* timetoa(const time_t *time, bool utc) return buf; } -/* +/** * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calender time */ time_t asn1totime(const chunk_t *utctime, asn1_t type) @@ -300,19 +309,20 @@ time_t asn1totime(const chunk_t *utctime, asn1_t type) return mktime(&t) - timezone - tz_offset; } -/* +/** * Initializes the internal context of the ASN.1 parser */ void asn1_init(asn1_ctx_t *ctx, chunk_t blob, u_int level0, bool implicit) { - logger = logger_manager->get_logger(logger_manager, ASN1); + asn1_init_logger(); + ctx->blobs[0] = blob; ctx->level0 = level0; ctx->implicit = implicit; memset(ctx->loopAddr, '\0', sizeof(ctx->loopAddr)); } -/* +/** * print the value of an ASN.1 simple object */ static void debug_asn1_simple_object(chunk_t object, asn1_t type) @@ -348,7 +358,7 @@ static void debug_asn1_simple_object(chunk_t object, asn1_t type) logger->log_chunk(logger, RAW|LEVEL1, "", object); } -/* +/** * Parses and extracts the next ASN.1 object */ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *object, u_int *level, asn1_ctx_t *ctx) @@ -479,7 +489,7 @@ bool extract_object(asn1Object_t const *objects, u_int *objectID, chunk_t *objec return TRUE; } -/* +/** * parse an ASN.1 simple type */ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name) @@ -515,7 +525,7 @@ bool parse_asn1_simple_object(chunk_t *object, asn1_t type, u_int level, const c return TRUE; } -/* +/** * extracts an algorithmIdentifier */ int parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters) @@ -558,6 +568,8 @@ bool is_asn1(chunk_t blob) u_int len; u_char tag = *blob.ptr; + asn1_init_logger(); + if (tag != ASN1_SEQUENCE && tag != ASN1_SET) { logger->log(logger, ERROR|LEVEL2, " file content is not binary ASN.1"); @@ -572,7 +584,7 @@ bool is_asn1(chunk_t blob) return TRUE; } -/* +/** * codes ASN.1 lengths up to a size of 16'777'215 bytes */ void code_asn1_length(size_t length, chunk_t *code) @@ -605,7 +617,7 @@ void code_asn1_length(size_t length, chunk_t *code) } } -/* +/** * build an empty asn.1 object with tag and length fields already filled in */ u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen) @@ -634,7 +646,7 @@ u_char* build_asn1_object(chunk_t *object, asn1_t type, size_t datalen) return pos; } -/* +/** * build a simple ASN.1 object */ chunk_t asn1_simple_object(asn1_t tag, chunk_t content) @@ -648,7 +660,8 @@ chunk_t asn1_simple_object(asn1_t tag, chunk_t content) return object; } -/* Build an ASN.1 object from a variable number of individual chunks. +/** + * Build an ASN.1 object from a variable number of individual chunks. * Depending on the mode, chunks either are moved ('m') or copied ('c'). */ chunk_t asn1_wrap(asn1_t type, const char *mode, ...) @@ -696,7 +709,7 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...) return construct; } -/* +/** * convert a MP integer into a DER coded ASN.1 object */ chunk_t asn1_integer_from_mpz(const mpz_t value) @@ -709,7 +722,7 @@ chunk_t asn1_integer_from_mpz(const mpz_t value) return asn1_wrap(ASN1_INTEGER, "m", n); } -/* +/** * convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format */ chunk_t timetoasn1(const time_t *time, asn1_t type) diff --git a/src/charon/lib/asn1/pem.c b/src/charon/lib/asn1/pem.c index b02268dd9..d3a6986eb 100755 --- a/src/charon/lib/asn1/pem.c +++ b/src/charon/lib/asn1/pem.c @@ -1,6 +1,5 @@ /* - * Copyright (C) 2005 Jan Hutter, Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -21,14 +20,27 @@ #include <stddef.h> #include <sys/types.h> +#include "asn1.h" #include "pem.h" #include "ttodata.h" +#include <utils/lexparser.h> +#include <utils/logger_manager.h> #include <crypto/hashers/hasher.h> #include <crypto/crypters/crypter.h> +static logger_t *logger = NULL; -/* +/** + * initializes the PEM logger + */ +static void pem_init_logger() +{ + if (logger == NULL) + logger = logger_manager->get_logger(logger_manager, ASN1); +} + +/** * check the presence of a pattern in a character string */ static bool present(const char* pattern, chunk_t* ch) @@ -44,15 +56,7 @@ static bool present(const char* pattern, chunk_t* ch) return FALSE; } -/* - * compare string with chunk - */ -static bool match(const char *pattern, const chunk_t *ch) -{ - return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0; -} - -/* +/** * find a boundary of the form -----tag name----- */ static bool find_boundary(const char* tag, chunk_t *line) @@ -73,6 +77,8 @@ static bool find_boundary(const char* tag, chunk_t *line) { if (present("-----", line)) { + logger->log(logger, CONTROL|LEVEL2, + " -----%s %.*s-----", tag, (int)name.len, name.ptr); return TRUE; } line->ptr++; line->len--; name.len++; @@ -81,92 +87,15 @@ static bool find_boundary(const char* tag, chunk_t *line) } /* - * eat whitespace - */ -static void eat_whitespace(chunk_t *src) -{ - while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t')) - { - src->ptr++; src->len--; - } -} - -/* - * extracts a token ending with a given termination symbol - */ -static bool extract_token(chunk_t *token, char termination, chunk_t *src) -{ - u_char *eot = memchr(src->ptr, termination, src->len); - - /* initialize empty token */ - *token = CHUNK_INITIALIZER; - - if (eot == NULL) /* termination symbol not found */ - { - return FALSE; - } - - /* extract token */ - token->ptr = src->ptr; - token->len = (u_int)(eot - src->ptr); - - /* advance src pointer after termination symbol */ - src->ptr = eot + 1; - src->len -= (token->len + 1); - - return TRUE; -} - -/* - * extracts a name: value pair from the PEM header - */ -static bool extract_parameter(chunk_t *name, chunk_t *value, chunk_t *line) -{ - /* extract name */ - if (!extract_token(name,':', line)) - { - return FALSE; - } - - eat_whitespace(line); - - /* extract value */ - *value = *line; - return TRUE; -} - -/* - * fetches a new line terminated by \n or \r\n - */ -static bool fetchline(chunk_t *src, chunk_t *line) -{ - if (src->len == 0) /* end of src reached */ - return FALSE; - - if (extract_token(line, '\n', src)) - { - if (line->len > 0 && *(line->ptr + line->len -1) == '\r') - line->len--; /* remove optional \r */ - } - else /*last line ends without newline */ - { - *line = *src; - src->ptr += src->len; - src->len = 0; - } - return TRUE; -} - -/* * decrypts a DES-EDE-CBC encrypted data block */ -static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase) +static err_t pem_decrypt(chunk_t *blob, chunk_t *iv, const char *passphrase) { hasher_t *hasher; crypter_t *crypter; chunk_t hash; chunk_t decrypted; - chunk_t pass = {passphrase, strlen(passphrase)}; + chunk_t pass = {(char*)passphrase, strlen(passphrase)}; chunk_t key = {alloca(24), 24}; u_int8_t padding, *last_padding_pos, *first_padding_pos; @@ -203,11 +132,11 @@ static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase) while (--last_padding_pos > first_padding_pos) { if (*last_padding_pos != padding) - return FALSE; + return "invalid passphrase"; } /* remove padding */ blob->len -= padding; - return TRUE; + return NULL; } /* Converts a PEM encoded file into its binary form @@ -215,7 +144,7 @@ static status_t pem_decrypt(chunk_t *blob, chunk_t *iv, char *passphrase) * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993 * RFC 934 Message Encapsulation, January 1985 */ -status_t pemtobin(chunk_t *blob, char *pass) +err_t pem_to_bin(chunk_t *blob, const char *passphrase, bool *pgp) { typedef enum { PEM_PRE = 0, @@ -244,6 +173,8 @@ status_t pemtobin(chunk_t *blob, char *pass) iv.ptr = iv_buf; iv.len = 0; + pem_init_logger(); + while (fetchline(&src, &line)) { if (state == PEM_PRE) @@ -277,8 +208,9 @@ status_t pemtobin(chunk_t *blob, char *pass) continue; } - /* we are looking for a name: value pair */ - if (!extract_parameter(&name, &value, &line)) + /* we are looking for a parameter: value pair */ + logger->log(logger, CONTROL|LEVEL2, " %.*s", (int)line.len, line.ptr); + if (!extract_parameter_value(&name, &value, &line)) continue; if (match("Proc-Type", &name) && *value.ptr == '4') @@ -294,12 +226,12 @@ status_t pemtobin(chunk_t *blob, char *pass) /* we support DES-EDE3-CBC encrypted files, only */ if (!match("DES-EDE3-CBC", &dek)) - return NOT_SUPPORTED; + return "encryption algorithm not supported"; eat_whitespace(&value); ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len); if (ugh) - return PARSE_ERROR; + return "error in IV"; iv.len = len; } @@ -316,6 +248,17 @@ status_t pemtobin(chunk_t *blob, char *pass) data = line; } + /* check for PGP armor checksum */ + if (*data.ptr == '=') + { + *pgp = TRUE; + data.ptr++; + data.len--; + logger->log(logger, CONTROL|LEVEL2, " Armor checksum: %.*s", + (int)data.len, data.ptr); + continue; + } + ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len); if (ugh) { @@ -334,10 +277,68 @@ status_t pemtobin(chunk_t *blob, char *pass) blob->len = dst.len; if (state != PEM_POST) - return PARSE_ERROR; + return "file coded in unknown format, discarded"; + + return (encrypted)? pem_decrypt(blob, &iv, passphrase) : NULL; +} + +/* load a coded key or certificate file with autodetection + * of binary DER or base64 PEM ASN.1 formats and armored PGP format + */ +bool pem_asn1_load_file(const char *filename, const char *passphrase, + const char *type, chunk_t *blob, bool *pgp) +{ + err_t ugh = NULL; + + FILE *fd = fopen(filename, "r"); + + pem_init_logger(); + + if (fd) + { + int bytes; + fseek(fd, 0, SEEK_END ); + blob->len = ftell(fd); + rewind(fd); + blob->ptr = malloc(blob->len); + bytes = fread(blob->ptr, 1, blob->len, fd); + fclose(fd); + logger->log(logger, CONTROL, "loaded %s file '%s' (%d bytes)", type, filename, bytes); + + *pgp = FALSE; + + /* try DER format */ + if (is_asn1(*blob)) + { + logger->log(logger, CONTROL|LEVEL1, " file coded in DER format"); + return TRUE; + } + + /* try PEM format */ + ugh = pem_to_bin(blob, passphrase, pgp); + + if (ugh == NULL) + { + if (*pgp) + { + logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format"); + return TRUE; + } + if (is_asn1(*blob)) + { + logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format"); + return TRUE; + } + ugh = "file coded in unknown format, discarded"; + } - if (encrypted) - return pem_decrypt(blob, &iv, pass); + /* a conversion error has occured */ + logger->log(logger, ERROR, " %s", ugh); + chunk_free(blob); + } else - return SUCCESS; + { + logger->log(logger, ERROR, "could not open %s file '%s'", type, filename); + } + return FALSE; } diff --git a/src/charon/lib/asn1/pem.h b/src/charon/lib/asn1/pem.h index a4332fd34..30621fa24 100755 --- a/src/charon/lib/asn1/pem.h +++ b/src/charon/lib/asn1/pem.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2006 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2001-2004 Andreas Steffen, Zuercher Hochschule Winterthur * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -20,6 +19,9 @@ #include <types.h> -status_t pemtobin(chunk_t *blob, char *pass); +err_t pem_to_bin(chunk_t *blob, const char *passphrase, bool *pgp); + +bool pem_asn1_load_file(const char *filename, const char *passphrase, + const char *type, chunk_t *blob, bool *pgp); #endif /*PEM_H_*/ diff --git a/src/charon/lib/asn1/ttodata.h b/src/charon/lib/asn1/ttodata.h index d57244ef5..b2b5adefd 100644 --- a/src/charon/lib/asn1/ttodata.h +++ b/src/charon/lib/asn1/ttodata.h @@ -22,8 +22,6 @@ #define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/ #define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */ -typedef const char *err_t; /* error message, or NULL for success */ - err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed); diff --git a/src/charon/lib/crypto/rsa/rsa_private_key.c b/src/charon/lib/crypto/rsa/rsa_private_key.c index 358653f0e..86a38cbfe 100644 --- a/src/charon/lib/crypto/rsa/rsa_private_key.c +++ b/src/charon/lib/crypto/rsa/rsa_private_key.c @@ -29,6 +29,7 @@ #include <daemon.h> #include <asn1/asn1.h> +#include <asn1/pem.h> /* * Oids for hash algorithms are defined in @@ -736,37 +737,17 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob) /* * see header - * TODO: PEM files */ rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase) { - chunk_t chunk; - struct stat stb; - FILE *file; - char *buffer; - - if (stat(filename, &stb) == -1) - { - return NULL; - } - - buffer = alloca(stb.st_size); - - file = fopen(filename, "r"); - if (file == NULL) - { - return NULL; - } - - if (fread(buffer, stb.st_size, 1, file) != 1) - { - fclose(file); + bool pgp = FALSE; + chunk_t chunk = CHUNK_INITIALIZER; + rsa_private_key_t *key = NULL; + + if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp)) return NULL; - } - fclose(file); - - chunk.ptr = buffer; - chunk.len = stb.st_size; - - return rsa_private_key_create_from_chunk(chunk); + + key = rsa_private_key_create_from_chunk(chunk); + free(chunk.ptr); + return key; } diff --git a/src/charon/lib/crypto/x509.c b/src/charon/lib/crypto/x509.c index 86a595618..91f9f191e 100755 --- a/src/charon/lib/crypto/x509.c +++ b/src/charon/lib/crypto/x509.c @@ -28,13 +28,11 @@ #include "x509.h" #include <daemon.h> -#include <asn1/asn1.h> #include <asn1/oid.h> +#include <asn1/asn1.h> +#include <asn1/pem.h> #include <utils/logger_manager.h> -typedef const char *err_t; /* error message, or NULL for success */ - - #define BUF_LEN 512 #define RSA_MIN_OCTETS (512 / 8) #define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits" @@ -905,33 +903,14 @@ x509_t *x509_create_from_chunk(chunk_t chunk) */ x509_t *x509_create_from_file(char *filename) { - struct stat stb; - FILE *file; - char *buffer; - chunk_t chunk; - - if (stat(filename, &stb) == -1) - { - return NULL; - } - - buffer = alloca(stb.st_size); - - file = fopen(filename, "r"); - if (file == NULL) - { - return NULL; - } - - if (fread(buffer, stb.st_size, 1, file) == -1) - { - fclose(file); + bool pgp = FALSE; + chunk_t chunk = CHUNK_INITIALIZER; + x509_t *cert = NULL; + + if (!pem_asn1_load_file(filename, "", "certificate", &chunk, &pgp)) return NULL; - } - fclose(file); - - chunk.ptr = buffer; - chunk.len = stb.st_size; - - return x509_create_from_chunk(chunk); + + cert = x509_create_from_chunk(chunk); + free(chunk.ptr); + return cert; } diff --git a/src/charon/lib/types.h b/src/charon/lib/types.h index 0e0782b31..4af9bc43d 100644 --- a/src/charon/lib/types.h +++ b/src/charon/lib/types.h @@ -37,6 +37,11 @@ typedef int bool; #define FALSE 0 #define TRUE 1 +/** + * error message, or NULL for success + */ +typedef const char *err_t; + typedef enum status_t status_t; /** diff --git a/src/charon/lib/utils/Makefile.utils b/src/charon/lib/utils/Makefile.utils index 1c82283d7..c04f3b1df 100644 --- a/src/charon/lib/utils/Makefile.utils +++ b/src/charon/lib/utils/Makefile.utils @@ -18,10 +18,14 @@ LIB_OBJS+= $(BUILD_DIR)leak_detective.o $(BUILD_DIR)leak_detective.o : $(UTILS_DIR)leak_detective.c $(UTILS_DIR)leak_detective.h $(CC) $(CFLAGS) -c -o $@ $< +LIB_OBJS+= $(BUILD_DIR)lexparser.o +$(BUILD_DIR)lexparser.o : $(UTILS_DIR)lexparser.c $(UTILS_DIR)lexparser.h + $(CC) $(CFLAGS) -c -o $@ $< + LIB_OBJS+= $(BUILD_DIR)linked_list.o $(BUILD_DIR)linked_list.o : $(UTILS_DIR)linked_list.c $(UTILS_DIR)linked_list.h $(CC) $(CFLAGS) -c -o $@ $< - + LIB_OBJS+= $(BUILD_DIR)logger.o $(BUILD_DIR)logger.o : $(UTILS_DIR)logger.c $(UTILS_DIR)logger.h $(CC) $(CFLAGS) -c -o $@ $< diff --git a/src/charon/lib/utils/lexparser.c b/src/charon/lib/utils/lexparser.c new file mode 100644 index 000000000..e3bb3d1f9 --- /dev/null +++ b/src/charon/lib/utils/lexparser.c @@ -0,0 +1,135 @@ +/** + * @file lexparser.c + * + * @brief lexical parser for text-based configuration files + * + */ + +/* + * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <string.h> + +#include "lexparser.h" + + +/** + * eat whitespace + */ +bool eat_whitespace(chunk_t *src) +{ + while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t')) + { + src->ptr++; src->len--; + } + return src->len > 0 && *src->ptr != '#'; +} + +/** + * compare string with chunk + */ +bool match(const char *pattern, const chunk_t *ch) +{ + return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0; +} + +/** + * extracts a token ending with a given termination symbol + */ +bool extract_token(chunk_t *token, const char termination, chunk_t *src) +{ + u_char *eot = memchr(src->ptr, termination, src->len); + + /* initialize empty token */ + *token = CHUNK_INITIALIZER; + + if (eot == NULL) /* termination symbol not found */ + { + return FALSE; + } + + /* extract token */ + token->ptr = src->ptr; + token->len = (u_int)(eot - src->ptr); + + /* advance src pointer after termination symbol */ + src->ptr = eot + 1; + src->len -= (token->len + 1); + + return TRUE; +} + +/** + * fetches a new line terminated by \n or \r\n + */ +bool fetchline(chunk_t *src, chunk_t *line) +{ + if (src->len == 0) /* end of src reached */ + return FALSE; + + if (extract_token(line, '\n', src)) + { + if (line->len > 0 && *(line->ptr + line->len -1) == '\r') + line->len--; /* remove optional \r */ + } + else /*last line ends without newline */ + { + *line = *src; + src->ptr += src->len; + src->len = 0; + } + return TRUE; +} + +err_t extract_value(chunk_t *value, chunk_t *line) +{ + char delimiter = ' '; + + if (!eat_whitespace(line)) + { + return "missing value"; + } + if (*line->ptr == '\'' || *line->ptr == '"') + { + delimiter = *line->ptr; + line->ptr++; line->len--; + } + if (!extract_token(value, delimiter, line)) + { + if (delimiter == ' ') + { + *value = *line; + } + else + { + return "missing second delimiter"; + } + } + return NULL; +} + +/** + * extracts a parameter: value pair + */ +err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line) +{ + /* extract name */ + if (!extract_token(name,':', line)) + { + return "missing ':'"; + } + + /* extract value */ + return extract_value(value, line); +} diff --git a/src/charon/lib/utils/lexparser.h b/src/charon/lib/utils/lexparser.h new file mode 100644 index 000000000..29c1bf701 --- /dev/null +++ b/src/charon/lib/utils/lexparser.h @@ -0,0 +1,57 @@ +/** + * @file lexparser.h + * + * @brief lexical parser for text-based configuration files + * + */ + +/* + * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <types.h> + +/** + * @brief Eats whitespace + */ +bool eat_whitespace(chunk_t *src); + +/** + * @brief Compare null-terminated pattern with chunk + */ +bool match(const char *pattern, const chunk_t *ch); + +/** + * @brief Extracts a token ending with a given termination symbol + */ +bool extract_token(chunk_t *token, const char termination, chunk_t *src); + +/** + * @brief Fetches a new text line terminated by \n or \r\n + */ +bool fetchline(chunk_t *src, chunk_t *line); + +/** + * @brief Extracts a value that might be single or double quoted + */ +err_t extract_value(chunk_t *value, chunk_t *line); + +/** + * @brief extracts a name: value pair from a text line + */ +err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line); + +/** + * @brief extracts a parameter: value from a text line + */ +err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line); diff --git a/src/charon/lib/utils/logger.c b/src/charon/lib/utils/logger.c index fdaeddff0..151fbfd50 100644 --- a/src/charon/lib/utils/logger.c +++ b/src/charon/lib/utils/logger.c @@ -132,11 +132,15 @@ static void prepend_prefix(private_logger_t *this, log_level_t loglevel, const c */ static int get_priority(log_level_t loglevel) { + if (loglevel & ERROR) + { + return LOG_AUTHPRIV|LOG_ERR; + } if (loglevel & AUDIT) { return LOG_AUTHPRIV|LOG_INFO; } - return LOG_DAEMON|LOG_DEBUG; + return LOG_AUTHPRIV|LOG_DEBUG; } /** |