- applied patch from andreas

- pem loading
	- secrets file parsing
	- ikev2 testcase
	- some other additions here and there
This commit is contained in:
Martin Willi
2006-05-04 07:55:42 +00:00
parent 8744148f55
commit 9820c0e208
41 changed files with 1234 additions and 842 deletions
+34 -21
View File
@@ -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)
+103 -102
View File
@@ -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++;
@@ -80,93 +86,16 @@ static bool find_boundary(const char* tag, chunk_t *line)
return FALSE;
}
/*
* 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";
if (encrypted)
return pem_decrypt(blob, &iv, pass);
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";
}
/* 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;
}
+5 -3
View File
@@ -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_*/
-2
View File
@@ -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);
+10 -29
View File
@@ -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)
{
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;
}
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);
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;
}
+11 -32
View File
@@ -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)
{
bool pgp = FALSE;
chunk_t chunk = CHUNK_INITIALIZER;
x509_t *cert = NULL;
if (!pem_asn1_load_file(filename, "", "certificate", &chunk, &pgp))
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);
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;
}
+5
View File
@@ -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;
/**
+5 -1
View File
@@ -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 $@ $<
+135
View File
@@ -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);
}
+57
View File
@@ -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);
+5 -1
View File
@@ -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;
}
/**