- Introduce (at least a basic form of) certificate validation
+ Support X.509 certificate chains
- Derive GnuTLS priority string automatically from credentials for localid
-- Migrate from fprintf (stderr, ...) to syslog()
++ Migrate from fprintf (stderr, ...) to syslog()
-# tlspool.conf - Configuration of the TLS pool
+# tlspool.conf - Configuration of the TLS Pool
#
# Lines in this file may only hold one of the following forms:
# - nothing: ignored
#
#
-# The TLS pool is a daemon. Set its PID file here, to be used in scripts.
+# The TLS Pool is a daemon. Set its PID file here, to be used in scripts.
#
daemon_pidfile /var/run/tlspool.pid
#
-# The TLS pool listens to a UNIX domain socket, reachable to users and groups
+# The TLS Pool listens to a UNIX domain socket, reachable to users and groups
# with the proper permissions. Use mode 0660 to permit same-user and
-# same-group access to the TLS pool.
+# same-group access to the TLS Pool.
#
# Note that initial root privileges are needed to be able to change to
# another socket_user and possibly to change the socket_group. These
socket_name /var/run/tlspool.sock
#
-# The TLS pool usually drops privileges to a lower-ordered user, as
+# The TLS Pool usually drops privileges to a lower-ordered user, as
# specified below. Note that the PKCS #11 interface is a library,
# so it may suffer from a chroot if it operates on locally stored
# data that is not available under the chroot environment.
daemon_group tlspool
#
-# The TLS pool is an application layer over PKCS #11. Configure which
+# The TLS Pool sends output to syslog, using an identity "tlspool" with the
+# process number and the daemon facility.
+#
+# log_level is set to the minimum level to log. It is set to one of
+# EMERG(ENCY), ALERT, CRIT(ICAL), ERR(OR), WARN(ING), NOT(IC)E, INFO
+# or DEBUG, which is a list ordered from quiet to verbose. Brackets
+# show what may be taken out to abbreviate a work; you may use * as
+# an alias for DEBUG.
+#
+# log_filter is a comma-separated list of words that signify the kind of
+# debugging output to show. Set to * to produce all possible output.
+# Recognised values include:
+# - TLS for TLS-level error messages
+# - PKCS11 for errors in PKCS #11 connections
+# - DB for errors related to management database handling
+# - FILES for errors related to the file system
+# - CRYPTO for cryptographic information
+# - CERT for certificate-related informaction (covers multiple cert types)
+# - USER for errors related to user interactions (such as PIN entry)
+# - AUTHN/AUTHZ/CREDS/SESSION are not yet generated, and may not be specified
+# - COPYCAT for details about the copying between TLS and plaintext
+# - UNIXSOCK for all details related to the UNIX socket of the TLS Pool
+# - DAEMON for daemon-generic notices
+#
+# log_stderr can be set to case-insensitive YES or 1 or * to specify
+# that the output should go to stderr. Conversely, setting it to 0
+# or case-insensitive NO disables copying logger output to stderr.
+#
+# The loudest logging possible is obtained by setting all variables to *
+#
+log_level *
+log_filter *
+log_stderr *
+
+#
+# The TLS Pool is an application layer over PKCS #11. Configure which
# PKCS #11 implementation library is used to store certificates and keys.
#
# Select the storage profile to be used for OpenPGP keys; they should
# login to the token.
#
# When no pkcs11_pin is available to a PKCS #11 token, it must be
-# submitted to a running TLS pool daemon by running tlspool a second
+# submitted to a running TLS Pool daemon by running tlspool a second
# time, with the -p option. This action will make it iterate over
# all tokens that failed to login yet, and present a PIN request for
# each of them. When all tokens have successfully logged in, then
pkcs11_token pkcs11:manufacturer=SoftHSM%20project;model=SoftHSM%20v2
#
-# The TLS pool uses a local LDAP proxy which resolves distinguishedNames
+# The TLS Pool uses a local LDAP proxy which resolves distinguishedNames
# ending in dc ,dc to remote LDAP servers. It should also store or find
# local public information, such as OpenPGP keys and X.509 certificates.
#
ldap_proxy ldap://[2001:db8::389:2]
#
-# The TLS pool can use memcache as a storage facility for authentication
+# The TLS Pool can use memcache as a storage facility for authentication
# and authorization results. It can be setup with an expiration time as
# is desirable; note that local programs have the ability to bypass the
# cache, so as to ensure tight authentication for the most critical tasks.
#
# Define additional services for Authentication, Authorization and
-# Accounting on top of the minimum requirements of the TLS pool.
+# Accounting on top of the minimum requirements of the TLS Pool.
# These requirements will be configured as a RADIUS service.
#
# Each of these entries is optional, and entirely independent of the
/* config.c */
char *cfg_p11pin (void);
+unsigned int cfg_log_perror (void);
+unsigned int cfg_log_level (void);
+unsigned int cfg_log_filter (void);
+
/* error.c -- Mapping various error code systems to others.
*
* function that is later provided to the E_x2y functions.
*/
+void setup_error (void);
+void cleanup_error (void);
typedef int gtls_error;
typedef int db_error;
void error_db2gnutls2posix (int *gtls_errno, int db_errno, char *opt_errstr);
void error_gnutls2posix (int gtls_errno, char *opt_errstr);
+
+/* Log a message to syslog (assuming that the configuration wants it) */
+void tlog (unsigned int logmask, int priority, char *format, ...);
+
+
+/* Loglevel masking words, to help weed out logging output */
+#define TLOG_TLS 0x00000001
+#define TLOG_PKCS11 0x00000002
+#define TLOG_DB 0x00000004
+#define TLOG_FILES 0x00000008
+#define TLOG_CRYPTO 0x00000010
+#define TLOG_CERT 0x00000020
+#define TLOG_USER 0x00000100
+// Unused: #define TLOG_AUTHN 0x00000200
+// Unused: #define TLOG_AUTHZ 0x00000400
+// Unused: #define TLOG_CREDS 0x00000800
+// Unused: #define TLOG_SESSION 0x00001000
+#define TLOG_COPYCAT 0x00002000
+#define TLOG_UNIXSOCK 0x00004000
+#define TLOG_DAEMON 0x00008000
+
#endif //TLSPOOL_INTERNAL_H
#include <sys/file.h>
#include <sys/un.h>
+#include <syslog.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <ldap.h>
#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
#include <gnutls/pkcs11.h>
+#include <tlspool/internal.h>
+
#include <libmemcached/memcached.h>
static LDAP *ldap_handle;
CFGVAR_RADIUS_AUTHN,
CFGVAR_RADIUS_AUTHZ,
CFGVAR_RADIUS_ACCT,
+ CFGVAR_LOG_LEVEL,
+ CFGVAR_LOG_FILTER,
+ CFGVAR_LOG_STDERR,
//
CFGVAR_LENGTH,
CFGVAR_NONE = -1
"radius_authn", cfg_setvar, CFGVAR_RADIUS_AUTHN,
"radius_authz", cfg_setvar, CFGVAR_RADIUS_AUTHZ,
"radius_acct", cfg_setvar, CFGVAR_RADIUS_ACCT,
+ "log_level", cfg_setvar, CFGVAR_LOG_LEVEL,
+ "log_filter", cfg_setvar, CFGVAR_LOG_FILTER,
+ "log_stderr", cfg_setvar, CFGVAR_LOG_STDERR,
//
NULL, NULL, CFGVAR_NONE
};
+struct var2val {
+ char *name;
+ unsigned int optval;
+};
+
+struct var2val v2v_log_level [] = {
+ { "EMERG", LOG_EMERG },
+ { "EMERGENCY", LOG_EMERG },
+ { "ALERT", LOG_ALERT },
+ { "CRIT", LOG_CRIT },
+ { "CRITICAL", LOG_CRIT },
+ { "ERR", LOG_ERR },
+ { "ERROR", LOG_ERR },
+ { "WARNING", LOG_WARNING },
+ { "WARN", LOG_WARNING },
+ { "NOTICE", LOG_NOTICE },
+ { "NOTE", LOG_NOTICE },
+ { "INFO", LOG_INFO },
+ { "DEBUG", LOG_DEBUG },
+ { "*", LOG_DEBUG },
+ { NULL, 0 }
+};
+
+struct var2val v2v_log_filter [] = {
+ { "*", ~0 },
+ { "TLS", TLOG_TLS },
+ { "PKCS11", TLOG_PKCS11 },
+ { "DB", TLOG_DB },
+ { "FILES", TLOG_FILES },
+ { "CRYPTO", TLOG_CRYPTO },
+ { "CERT", TLOG_CERT },
+ { "USER", TLOG_USER },
+ // AUTHN/AUTHZ/CREDS/SESSION are not yet generated
+ { "COPYCAT", TLOG_COPYCAT },
+ { "UNIXSOCK", TLOG_UNIXSOCK },
+ { "DAEMON", TLOG_DAEMON },
+ { NULL, 0 }
+};
+
+struct var2val v2v_log_perror [] = {
+ { "YES", LOG_PERROR },
+ { "1", LOG_PERROR },
+ { "*", LOG_PERROR },
+ { "NO", 0 },
+ { "0", 0 },
+ { NULL, 0 }
+};
+
+
+
+static unsigned int parse_var2val (char *word, int wlen, struct var2val *patterns, unsigned int defaultvalue) {
+ if (word == NULL) {
+ return defaultvalue;
+ }
+ if (wlen < 0) {
+ wlen = strlen (word);
+ }
+ while (patterns->name) {
+ if (strlen (patterns->name) == wlen) {
+ if (strncasecmp (patterns->name, word, wlen) == 0) {
+ return patterns->optval;
+ }
+ }
+ patterns++;
+ }
+ return defaultvalue;
+}
+
+static unsigned int parse_var2val_list (char *wordlist, struct var2val *patterns, unsigned int defaultvalue) {
+ int comma;
+ unsigned int retval = 0;
+ if ((wordlist == NULL) || (*wordlist == '\0')) {
+ return defaultvalue;
+ }
+ while (*wordlist) {
+ comma = strcspn (wordlist, ",");
+ retval |= parse_var2val (wordlist, comma, patterns, 0);
+ wordlist += comma + 1;
+ }
+ return retval;
+}
+
+/* General configfile parser */
void parse_cfgfile (char *filename, int kill_competition) {
FILE *cf = fopen (filename, "r");
fprintf (stderr, "Out of memory duplicating configuration string\n");
exit (1);
}
+#ifdef DEBUG
fprintf (stdout, "DEBUG: SETUP %s AS %s\n", item, value);
+#endif
}
void unlink_pidfile (void) {
}
void cfg_user (char *item, int itemno, char *value) {
+#ifdef DEBUG
fprintf (stdout, "DEBUG: DECLARE %s AS %s\n", item, value);
+#endif
struct passwd *pwd = getpwnam (value);
if (!pwd) {
fprintf (stderr, "Failed to find username %s\n", value);
}
void cfg_group (char *item, int itemno, char *value) {
+#ifdef DEBUG
fprintf (stdout, "DEBUG: DECLARE %s AS %s\n", item, value);
+#endif
struct group *grp = getgrnam (value);
if (!grp) {
fprintf (stderr, "Failed to find group name %s\n", value);
}
}
+unsigned int cfg_log_perror (void) {
+ return parse_var2val (configvars [CFGVAR_LOG_STDERR], -1, v2v_log_perror, 0);
+}
+
+unsigned int cfg_log_level (void) {
+ return parse_var2val (configvars [CFGVAR_LOG_LEVEL], -1, v2v_log_level, LOG_ERR);
+}
+
+unsigned int cfg_log_filter (void) {
+ return parse_var2val_list (configvars [CFGVAR_LOG_FILTER], v2v_log_filter, ~0);
+}
+
static void free_p11pin (void) {
char *pin = configvars [CFGVAR_PKCS11_PIN];
if (pin) {
}
void cfg_p11path (char *item, int itemno, char *value) {
+#ifdef DEBUG
fprintf (stdout, "DEBUG: DECLARE %s AS %s\n", item, value);
+#endif
cfg_setvar (item, itemno, value);
//TODO:WHY?// free_p11pin ();
}
void cfg_p11token (char *item, int itemno, char *value) {
unsigned int token_seq = 0;
char *p11uri;
+#ifdef DEBUG
fprintf (stdout, "DEBUG: DECLARE %s AS %s\n", item, value);
+#endif
if (!configvars [CFGVAR_PKCS11_PATH]) {
fprintf (stderr, "You must specify pkcs11_path before any number of pkcs11_token\n");
exit (1);
exit (1);
}
while (gnutls_pkcs11_token_get_url (token_seq, 0, &p11uri) == 0) {
+#ifdef DEBUG
printf ("DEBUG: Found token URI %s\n", p11uri);
+#endif
//TODO// if (gnutls_pkcs11_token_get_info (p11uri, GNUTLS_PKCS11_TOKEN_LABEL-of-SERIAL-of-MANUFACTURER-of-MODEL, output, utput_size) == 0) { ... }
gnutls_free (p11uri);
token_seq++;
#include <unistd.h>
#include <string.h>
+#include <syslog.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
+
+#include <tlspool/internal.h>
void process_hangup (int hangupsignal) {
- fprintf (stderr, "DEBUG: Received signal %d as a hangup request\n");
+ tlog (TLOG_DAEMON, LOG_NOTICE, "Received signal %d as a hangup request");
hangup_service ();
}
perror ("Failed to setup HUP signal handler");
}
//TODO// close the common fd's 0/1/2
+ parse_cfgfile (cfgfile, kill_competition);
+ setup_error ();
+ tlog (TLOG_DAEMON, LOG_INFO, "TLS Pool started");
setup_handler ();
setup_pinentry ();
- parse_cfgfile (cfgfile, kill_competition);
run_service ();
- fprintf (stderr, "DEBUG: Cleanup started\n");
+ tlog (TLOG_DAEMON, LOG_DEBUG, "Preparing to stop -- Cleanup started");
cleanup_pinentry ();
cleanup_handler ();
- fprintf (stderr, "DEBUG: Orderly shutdown seems to have worked\n");
+ cleanup_error ();
+ tlog (TLOG_DAEMON, LOG_DEBUG, "Orderly shutdown seems to have worked");
+ tlog (TLOG_DAEMON, LOG_INFO, "TLS Pool stopped");
break;
default:
- fprintf (stderr, "Started tlspool daemon on PID %d\n", pid);
break;
}
}
--- /dev/null
+/* error.c -- Map error codes between the various error subsystems.
+ *
+ * From: Rick van Rein <rick@openfortress.nl>
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <syslog.h>
+#include <errno.h>
+
+#include <db.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
+
+#include <tlspool/internal.h>
+
+
+/* Data structures for logging configuration */
+
+static unsigned int log_filter;
+
+
+/* Setup logging structures for error reporting.
+ */
+void setup_error (void) {
+ unsigned int log_perror;
+ unsigned int log_level;
+ log_perror = cfg_log_perror ();
+ log_level = cfg_log_level ();
+ log_filter = cfg_log_filter ();
+ openlog ("TLS Pool", LOG_CONS | LOG_PID | log_perror, log_level);
+}
+
+void cleanup_error (void) {
+ closelog ();
+}
+
+
+/* Forward a message to syslog, assuming that the configuration wants it */
+
+void tlog (unsigned int logmask, int priority, char *format, ...) {
+ va_list varg;
+ va_start (varg, format);
+ if ((logmask & log_filter) != 0) {
+ vsyslog (priority, format, varg);
+ }
+ va_end (varg);
+}
+
+
+
+/* Mapping for error codes between the various subsystems in use. */
+
+void error_db2gnutls2posix (int *gtls_errno, int db_errno, char *opt_errstr) {
+ if (db_errno == 0) {
+ return;
+ }
+ if (opt_errstr) {
+ tlog (TLOG_DB, LOG_ERR, "DB error: %s", opt_errstr);
+ }
+ if (errno == 0) {
+ switch (db_errno) {
+ case DB_BUFFER_SMALL:
+ case DB_LOG_BUFFER_FULL:
+ errno = ENOBUFS;
+ break;
+ case DB_DONOTINDEX:
+ case DB_KEYEMPTY:
+ case DB_FOREIGN_CONFLICT:
+ case DB_PAGE_NOTFOUND:
+ case DB_SECONDARY_BAD:
+ errno = ENOKEY;
+ break;
+ case DB_KEYEXIST:
+ errno = EACCES;
+ break;
+ case DB_LOCK_DEADLOCK:
+ errno = EDEADLK;
+ break;
+ case DB_LOCK_NOTGRANTED:
+ errno = ENOLCK;
+ break;
+ case DB_NOSERVER:
+ case DB_NOSERVER_HOME:
+ case DB_NOSERVER_ID:
+ case DB_REP_DUPMASTER:
+ case DB_REP_HANDLE_DEAD:
+ case DB_REP_HOLDELECTION:
+ case DB_REP_IGNORE:
+ case DB_REP_ISPERM:
+ case DB_REP_JOIN_FAILURE:
+ case DB_REP_LEASE_EXPIRED:
+ case DB_REP_LOCKOUT:
+ case DB_REP_NEWSITE:
+ case DB_REP_NOTPERM:
+ case DB_REP_UNAVAIL:
+ errno = EREMOTEIO;
+ break;
+ case DB_NOTFOUND:
+ errno = ENODATA;
+ break;
+ case DB_OLD_VERSION:
+ case DB_VERSION_MISMATCH:
+ errno = ENOEXEC;
+ break;
+ case DB_RUNRECOVERY:
+ case DB_VERIFY_BAD:
+ errno = ENOTRECOVERABLE;
+ break;
+ default:
+ errno = ENOSYS;
+ break;
+ }
+ }
+ if (*gtls_errno == GNUTLS_E_SUCCESS) {
+ *gtls_errno = GNUTLS_E_DB_ERROR;
+ }
+}
+
+void error_gnutls2posix (int gtls_errno, char *opt_errstr) {
+ register int newerrno;
+ if (gtls_errno == GNUTLS_E_SUCCESS) {
+ return;
+ }
+ if (errno != 0) {
+ return;
+ }
+ tlog (TLOG_TLS, LOG_ERR, "%s: %s",
+ opt_errstr? opt_errstr: "GnuTLS error",
+ gnutls_strerror (gtls_errno));
+ switch (gtls_errno) {
+ case GNUTLS_E_SUCCESS:
+ return;
+ case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM:
+ case GNUTLS_E_UNKNOWN_CIPHER_TYPE:
+ case GNUTLS_E_UNSUPPORTED_VERSION_PACKET:
+ case GNUTLS_E_UNWANTED_ALGORITHM:
+ case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
+ case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE:
+ case GNUTLS_E_X509_UNKNOWN_SAN:
+ case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
+ case GNUTLS_E_UNKNOWN_PK_ALGORITHM:
+ case GNUTLS_E_NO_TEMPORARY_RSA_PARAMS:
+ case GNUTLS_E_NO_COMPRESSION_ALGORITHMS:
+ case GNUTLS_E_NO_CIPHER_SUITES:
+ case GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED:
+ case GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE:
+ case GNUTLS_E_UNKNOWN_HASH_ALGORITHM:
+ case GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE:
+ case GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE:
+ case GNUTLS_E_NO_TEMPORARY_DH_PARAMS:
+ case GNUTLS_E_UNKNOWN_ALGORITHM:
+ case GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM:
+ case GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED:
+ case GNUTLS_E_X509_UNSUPPORTED_OID:
+ case GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE:
+ case GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL:
+ case GNUTLS_E_ECC_NO_SUPPORTED_CURVES:
+ case GNUTLS_E_ECC_UNSUPPORTED_CURVE:
+ case GNUTLS_E_X509_UNSUPPORTED_EXTENSION:
+ case GNUTLS_E_NO_CERTIFICATE_STATUS:
+ case GNUTLS_E_NO_APPLICATION_PROTOCOL:
+#ifdef GNUTLS_E_NO_SELF_TEST
+ case GNUTLS_E_NO_SELF_TEST:
+#endif
+ newerrno = EOPNOTSUPP;
+ break;
+ case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
+ case GNUTLS_E_INVALID_REQUEST:
+ newerrno = EINVAL;
+ break;
+ case GNUTLS_E_INVALID_SESSION:
+ case GNUTLS_E_REHANDSHAKE:
+ case GNUTLS_E_CERTIFICATE_KEY_MISMATCH:
+ newerrno = ENOTCONN;
+ break;
+ case GNUTLS_E_PUSH_ERROR:
+ case GNUTLS_E_PULL_ERROR:
+ case GNUTLS_E_PREMATURE_TERMINATION:
+ case GNUTLS_E_SESSION_EOF:
+ newerrno = ECONNRESET;
+ break;
+ case GNUTLS_E_UNEXPECTED_PACKET:
+ case GNUTLS_E_WARNING_ALERT_RECEIVED:
+ case GNUTLS_E_FATAL_ALERT_RECEIVED:
+ case GNUTLS_E_LARGE_PACKET:
+ case GNUTLS_E_ERROR_IN_FINISHED_PACKET:
+ case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET:
+ case GNUTLS_E_MPI_SCAN_FAILED:
+ case GNUTLS_E_DECRYPTION_FAILED:
+ case GNUTLS_E_DECOMPRESSION_FAILED:
+ case GNUTLS_E_COMPRESSION_FAILED:
+ case GNUTLS_E_BASE64_DECODING_ERROR:
+ case GNUTLS_E_MPI_PRINT_FAILED:
+ case GNUTLS_E_GOT_APPLICATION_DATA:
+ case GNUTLS_E_RECORD_LIMIT_REACHED:
+ case GNUTLS_E_ENCRYPTION_FAILED:
+ case GNUTLS_E_PK_ENCRYPTION_FAILED:
+ case GNUTLS_E_PK_DECRYPTION_FAILED:
+ case GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER:
+ case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
+ case GNUTLS_E_PKCS1_WRONG_PAD:
+ case GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION:
+ case GNUTLS_E_FILE_ERROR:
+ case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND:
+ case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND:
+ case GNUTLS_E_ASN1_DER_ERROR:
+ case GNUTLS_E_ASN1_VALUE_NOT_FOUND:
+ case GNUTLS_E_ASN1_GENERIC_ERROR:
+ case GNUTLS_E_ASN1_VALUE_NOT_VALID:
+ case GNUTLS_E_ASN1_TAG_ERROR:
+ case GNUTLS_E_ASN1_TAG_IMPLICIT:
+ case GNUTLS_E_ASN1_TYPE_ANY_ERROR:
+ case GNUTLS_E_ASN1_SYNTAX_ERROR:
+ case GNUTLS_E_ASN1_DER_OVERFLOW:
+ case GNUTLS_E_TOO_MANY_EMPTY_PACKETS:
+ case GNUTLS_E_TOO_MANY_HANDSHAKE_PACKETS:
+ case GNUTLS_E_SRP_PWD_PARSING_ERROR:
+ case GNUTLS_E_BASE64_ENCODING_ERROR:
+ case GNUTLS_E_OPENPGP_KEYRING_ERROR:
+ case GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR:
+ case GNUTLS_E_OPENPGP_SUBKEY_ERROR:
+ case GNUTLS_E_CRYPTO_ALREADY_REGISTERED:
+ case GNUTLS_E_HANDSHAKE_TOO_LARGE:
+ case GNUTLS_E_BAD_COOKIE:
+ case GNUTLS_E_PARSING_ERROR:
+ case GNUTLS_E_CERTIFICATE_LIST_UNSORTED:
+ case GNUTLS_E_NO_PRIORITIES_WERE_SET:
+#ifdef GNUTLS_E_PK_GENERATION_ERROR
+ case GNUTLS_E_PK_GENERATION_ERROR:
+#endif
+#ifdef GNUTLS_E_SELF_TEST_ERROR
+ case GNUTLS_E_SELF_TEST_ERROR:
+#endif
+#ifdef GNUTLS_E_SOCKETS_INIT_ERROR
+ case GNUTLS_E_SOCKETS_INIT_ERROR:
+#endif
+ newerrno = EIO;
+ break;
+ case GNUTLS_E_MEMORY_ERROR:
+ case GNUTLS_E_SHORT_MEMORY_BUFFER:
+ newerrno = ENOMEM;
+ break;
+ case GNUTLS_E_AGAIN:
+ newerrno = EAGAIN;
+ break;
+ case GNUTLS_E_EXPIRED:
+ case GNUTLS_E_TIMEDOUT:
+ newerrno = ETIMEDOUT;
+ break;
+ case GNUTLS_E_DB_ERROR:
+ newerrno = ENODATA;
+ break;
+ case GNUTLS_E_SRP_PWD_ERROR:
+ case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
+ case GNUTLS_E_HASH_FAILED:
+ case GNUTLS_E_PK_SIGN_FAILED:
+ case GNUTLS_E_CERTIFICATE_ERROR:
+ case GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION:
+ case GNUTLS_E_KEY_USAGE_VIOLATION:
+ case GNUTLS_E_NO_CERTIFICATE_FOUND:
+ case GNUTLS_E_OPENPGP_UID_REVOKED:
+ case GNUTLS_E_OPENPGP_GETKEY_FAILED:
+ case GNUTLS_E_PK_SIG_VERIFY_FAILED:
+ case GNUTLS_E_ILLEGAL_SRP_USERNAME:
+ case GNUTLS_E_INVALID_PASSWORD:
+ case GNUTLS_E_MAC_VERIFY_FAILED:
+ case GNUTLS_E_IA_VERIFY_FAILED:
+ case GNUTLS_E_UNKNOWN_SRP_USERNAME:
+ case GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR:
+ case GNUTLS_E_USER_ERROR:
+ case GNUTLS_E_AUTH_ERROR:
+ newerrno = EACCES;
+ break;
+ case GNUTLS_E_INTERRUPTED:
+ newerrno = EINTR;
+ break;
+ case GNUTLS_E_INTERNAL_ERROR:
+ case GNUTLS_E_CONSTRAINT_ERROR:
+ case GNUTLS_E_ILLEGAL_PARAMETER:
+ newerrno = EINVAL;
+ break;
+ case GNUTLS_E_SAFE_RENEGOTIATION_FAILED:
+ newerrno = ECONNREFUSED;
+ break;
+ case GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY:
+ case GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY:
+#ifdef GNUTLS_E_LIB_IN_ERROR_STATE
+ case GNUTLS_E_LIB_IN_ERROR_STATE:
+#endif
+ newerrno = ENOEXEC;
+ break;
+ case GNUTLS_E_RANDOM_FAILED:
+ newerrno = EBADF;
+ break;
+ case GNUTLS_E_CRYPTODEV_IOCTL_ERROR:
+ case GNUTLS_E_CRYPTODEV_DEVICE_ERROR:
+ case GNUTLS_E_HEARTBEAT_PONG_RECEIVED:
+ case GNUTLS_E_HEARTBEAT_PING_RECEIVED:
+ case GNUTLS_E_PKCS11_ERROR:
+ case GNUTLS_E_PKCS11_LOAD_ERROR:
+ case GNUTLS_E_PKCS11_PIN_ERROR:
+ case GNUTLS_E_PKCS11_SLOT_ERROR:
+ case GNUTLS_E_LOCKING_ERROR:
+ case GNUTLS_E_PKCS11_ATTRIBUTE_ERROR:
+ case GNUTLS_E_PKCS11_DEVICE_ERROR:
+ case GNUTLS_E_PKCS11_DATA_ERROR:
+ case GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR:
+ case GNUTLS_E_PKCS11_KEY_ERROR:
+ case GNUTLS_E_PKCS11_PIN_EXPIRED:
+ case GNUTLS_E_PKCS11_PIN_LOCKED:
+ case GNUTLS_E_PKCS11_SESSION_ERROR:
+ case GNUTLS_E_PKCS11_SIGNATURE_ERROR:
+ case GNUTLS_E_PKCS11_TOKEN_ERROR:
+ case GNUTLS_E_PKCS11_USER_ERROR:
+ case GNUTLS_E_CRYPTO_INIT_FAILED:
+ case GNUTLS_E_PKCS11_REQUESTED_OBJECT_NOT_AVAILBLE:
+ case GNUTLS_E_TPM_ERROR:
+ case GNUTLS_E_TPM_KEY_PASSWORD_ERROR:
+ case GNUTLS_E_TPM_SRK_PASSWORD_ERROR:
+ case GNUTLS_E_TPM_SESSION_ERROR:
+ case GNUTLS_E_TPM_KEY_NOT_FOUND:
+ case GNUTLS_E_TPM_UNINITIALIZED:
+ case GNUTLS_E_OCSP_RESPONSE_ERROR:
+ case GNUTLS_E_RANDOM_DEVICE_ERROR:
+ newerrno = EREMOTEIO;
+ break;
+ default:
+ newerrno = EIO;
+ break;
+ }
+ errno = newerrno;
+ return;
+}
#include <alloca.h>
#include <unistd.h>
+#include <syslog.h>
#include <errno.h>
#include <poll.h>
// File failed to load, so try to generate fresh DH params
int gtls_errno_stack0;
gtls_errno = GNUTLS_E_SUCCESS;
- fprintf (stderr, "DEBUG: Failed to load DH params from %s; generating fresh parameters\n", filename);
+ tlog (TLOG_CRYPTO, LOG_DEBUG, "Failed to load DH params from %s; generating fresh parameters", filename);
E_g2e ("Failed to generate DH params",
generate_dh_params ());
gtls_errno_stack0 = gtls_errno;
if (pemf != NULL) {
fwrite (pkcs3.data, 1, pkcs3.size, pemf);
fclose (pemf);
- fprintf (stderr, "DEBUG: Saved DH params to %s (best-effort)\n", filename);
+ tlog (TLOG_FILES, LOG_DEBUG, "Saved DH params to %s (best-effort)", filename);
}
E_gnutls_clear_errno ();
}
/* A log printing function
*/
void log_gnutls (int level, const char *msg) {
- fprintf (stderr, "GnuTLS_%d: %s", level, msg);
+ tlog (TLOG_TLS, level, "GnuTLS: %s", msg);
}
int gtls_errno = GNUTLS_E_SUCCESS;
//
// Basic library actions
- fprintf (stderr, "DEBUG: Compiled against GnuTLS version %s\n", GNUTLS_VERSION);
+ tlog (TLOG_TLS, LOG_DEBUG, "Compiled against GnuTLS version %s", GNUTLS_VERSION);
curver = gnutls_check_version (GNUTLS_VERSION);
- fprintf (stderr, "DEBUG: Running against %s GnuTLS version %s\n", curver? "acceptable": "OLDER", curver? curver: gnutls_check_version (NULL));
-fprintf (stderr, "Now errno=%d, gtls_errno=%d\n", errno, gtls_errno);
+ tlog (TLOG_TLS, LOG_DEBUG, "Running against %s GnuTLS version %s", curver? "acceptable": "OLDER", curver? curver: gnutls_check_version (NULL));
E_g2e ("GnuTLS global initialisation failed",
gnutls_global_init ());
E_gnutls_clear_errno ();
E_g2e ("GnuTLS PKCS #11 initialisation failed",
gnutls_pkcs11_init (
GNUTLS_PKCS11_FLAG_MANUAL, NULL));
-fprintf (stderr, "Now errno=%d, gtls_errno=%d\n", errno, gtls_errno);
//
// Setup logging / debugging
- gnutls_global_set_log_function (log_gnutls);
- gnutls_global_set_log_level (2);
-fprintf (stderr, "Now errno=%d, gtls_errno=%d\n", errno, gtls_errno);
+ if (cfg_log_level () == LOG_DEBUG) {
+ gnutls_global_set_log_function (log_gnutls);
+ gnutls_global_set_log_level (2);
+ }
//
// Setup DH parameters
E_g2e ("Loading DH params failed",
E_g2e ("Failed to setup GnuTLS callback credentials",
setup_handler_credentials ());
if (gtls_errno != GNUTLS_E_SUCCESS) {
- fprintf (stderr, "FATAL: GnuTLS setup failed: %s\n", gnutls_strerror (gtls_errno));
+ tlog (TLOG_TLS, LOG_CRIT, "FATAL: GnuTLS setup failed: %s", gnutls_strerror (gtls_errno));
exit (1);
}
//
// Setup the management databases
- fprintf (stderr, "DEBUG: Setting up management databases\n");
+ tlog (TLOG_DB, LOG_DEBUG, "Setting up management databases");
E_g2e ("Failed to setup management databases",
setup_management ());
if (errno != 0) {
- fprintf (stderr, "FATAL: TLS handler setup failed: %s\n", strerror (errno));
+ tlog (TLOG_DB, LOG_CRIT, "FATAL: Management databases setup failed: %s", strerror (errno));
exit (1);
}
}
inout [2].fd = master;
inout [0].events = inout [1].events = POLLIN;
inout [2].events = 0; // error events only
- printf ("DEBUG: Starting copycat cycle for local=%d, remote=%d\n", local, remote);
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Starting copycat cycle for local=%d, remote=%d", local, remote);
while (((inout [0].events | inout [1].events) & POLLIN) != 0) {
if (poll (inout, 3, -1) == -1) {
- printf ("DEBUG: Copycat polling returned an error\n");
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Copycat polling returned an error");
break; // Polling sees an error
}
if (inout [0].revents & POLLIN) {
// Read local and encrypt to remote
sz = recv (local, buf, sizeof (buf), MSG_DONTWAIT);
- printf ("DEBUG: Copycat received %d local bytes (or error<0) from %d\n", (int) sz, local);
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Copycat received %d local bytes (or error<0) from %d", (int) sz, local);
if (sz == -1) {
- fprintf (stderr, "Error while receiving: %s\n", strerror (errno));
+ tlog (TLOG_COPYCAT, LOG_ERR, "Error while receiving: %s", strerror (errno));
break; // stream error
} else if (sz == 0) {
inout [0].events &= ~POLLIN;
setsockopt (remote, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger));
gnutls_bye (wrapped, GNUTLS_SHUT_WR);
} else if (gnutls_record_send (wrapped, buf, sz) != sz) {
- fprintf (stderr, "gnutls_record_send() failed to pass on the requested bytes\n");
+ tlog (TLOG_COPYCAT, LOG_ERR, "gnutls_record_send() failed to pass on the requested bytes");
break; // communication error
} else {
- printf ("DEBUG: Copycat sent %d bytes to remote %d\n", (int) sz, remote);
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Copycat sent %d bytes to remote %d", (int) sz, remote);
}
}
if (inout [1].revents & POLLIN) {
// Read remote and decrypt to local
sz = gnutls_record_recv (wrapped, buf, sizeof (buf));
- printf ("DEBUG: Copycat received %d remote bytes from %d (or error if <0)\n", (int) sz, remote);
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Copycat received %d remote bytes from %d (or error if <0)", (int) sz, remote);
if (sz < 0) {
if (gnutls_error_is_fatal (sz)) {
- fprintf (stderr, "GnuTLS fatal error: %s\n", gnutls_strerror (sz));
+ tlog (TLOG_TLS, LOG_ERR, "GnuTLS fatal error: %s", gnutls_strerror (sz));
break; // stream error
} else {
- fprintf (stderr, "GnuTLS recoverable error: %s\n", gnutls_strerror (sz));
+ tlog (TLOG_TLS, LOG_INFO, "GnuTLS recoverable error: %s", gnutls_strerror (sz));
}
} else if (sz == 0) {
inout [1].events &= ~POLLIN;
} else if (send (local, buf, sz, MSG_DONTWAIT) != sz) {
break; // communication error
} else {
- printf ("DEBUG: Copycat sent %d bytes to local %d\n", (int) sz, local);
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Copycat sent %d bytes to local %d", (int) sz, local);
}
}
inout [0].revents &= ~(POLLIN | POLLHUP); // Thy copying cat?
inout [1].revents &= ~(POLLIN | POLLHUP); // Retract thee claws!
if ((inout [0].revents | inout [1].revents | inout [2].revents) & ~POLLIN) {
- printf ("DEBUG: Copycat polling returned a special condition\n");
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Copycat polling returned a special condition");
break; // Apparently, one of POLLERR, POLLHUP, POLLNVAL
}
}
- printf ("DEBUG: Ending copycat cycle for local=%d, remote=%d\n", local, remote);
+ tlog (TLOG_COPYCAT, LOG_DEBUG, "Ending copycat cycle for local=%d, remote=%d", local, remote);
}
}
if (*lid != '\0') {
if (strncmp (sni, lid, snilen) != 0) {
- fprintf (stderr, "DEBUG: SNI %s does not match preset local identity %s\n", sni, lid);
+ tlog (TLOG_TLS, LOG_ERR, "SNI %s does not match preset local identity %s", sni, lid);
E_g2e ("Requested SNI does not match local identity",
GNUTLS_E_NO_CERTIFICATE_FOUND);
return gtls_errno;
// Setup the lidtype parameter for responding
certtp = gnutls_certificate_type_get (session);
if (certtp == GNUTLS_CRT_OPENPGP) {
- fprintf (stderr, "DEBUG: Serving OpenPGP certificate request as a %s\n", rolestr);
+ tlog (TLOG_TLS, LOG_INFO, "Serving OpenPGP certificate request as a %s", rolestr);
lidtype = LID_TYPE_PGP;
} else if (certtp == GNUTLS_CRT_X509) {
- fprintf (stderr, "DEBUG: Serving X.509 certificate request as a %s\n", rolestr);
+ tlog (TLOG_TLS, LOG_INFO, "Serving X.509 certificate request as a %s", rolestr);
lidtype = LID_TYPE_X509;
} else {
// GNUTLS_CRT_RAW, GNUTLS_CRT_UNKNOWN, or other
- fprintf (stderr, "DEBUG: Funny sort of certificate retrieval attempted as a %s\n", rolestr);
+ tlog (TLOG_TLS, LOG_ERR, "Funny sort of certificate retrieval attempted as a %s", rolestr);
E_g2e ("Requested certtype is neither X.509 nor OpenPGP",
GNUTLS_E_CERTIFICATE_ERROR);
return gtls_errno;
if (cmd->lids [lidtype - LID_TYPE_MIN].data == NULL) {
uint32_t oldcmd = cmd->cmd.pio_cmd;
cmd->cmd.pio_cmd = PIOC_STARTTLS_LOCALID_V1;
- fprintf (stderr, "DEBUG: Calling send_callback_and_await_response with PIOC_STARTTLS_LOCALID_V1\n");
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Calling send_callback_and_await_response with PIOC_STARTTLS_LOCALID_V1");
cmd = send_callback_and_await_response (cmd);
- fprintf (stderr, "DEBUG: Processing callback response that sets lid:=\"%s\" for rid==\"%s\"\n", lid, rid);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Processing callback response that sets lid:=\"%s\" for rid==\"%s\"", lid, rid);
if (cmd->cmd.pio_cmd != PIOC_STARTTLS_LOCALID_V1) {
- fprintf (stderr, "DEBUG: Callback responses has bad command code\n");
+ tlog (TLOG_UNIXSOCK, LOG_ERR, "Callback response has bad command code");
cmd->cmd.pio_cmd = oldcmd;
return GNUTLS_E_CERTIFICATE_ERROR;
}
&p11priv,
&certdatum.data,
&certdatum.size);
- fprintf (stderr, "DEBUG: BDB entry has flags=0x%08x, p11priv=\"%s\", cert.size=%d\n", flags, p11priv, certdatum.size);
+ tlog (TLOG_DB, LOG_DEBUG, "BDB entry has flags=0x%08x, p11priv=\"%s\", cert.size=%d", flags, p11priv, certdatum.size);
//TODO// ok = ok && verify_cert_... (...); -- keyidlookup
if (!ok) {
gtls_errno = GNUTLS_E_CERTIFICATE_ERROR;
//
// Return the overral error code, hopefully GNUTLS_E_SUCCESS
-fprintf (stderr, "DEBUG: Returning %d / %s from clisrv_cert_retrieve()\n", gtls_errno, gnutls_strerror (gtls_errno));
+ tlog (TLOG_TLS, LOG_DEBUG, "Returning %d / %s from clisrv_cert_retrieve()", gtls_errno, gnutls_strerror (gtls_errno));
return gtls_errno;
}
certdatum->size,
&lenlen);
certlen += 1 + lenlen;
- fprintf (stderr, "DEBUG: Found LID_CHAINED certificate size %d\n", certlen);
+ tlog (TLOG_CERT, LOG_DEBUG, "Found LID_CHAINED certificate size %d", certlen);
if (certlen > certdatum->size) {
- fprintf (stderr, "ERROR: Refusing LID_CHAINED certificate beyond data size %d\n", certdatum->size);
+ tlog (TLOG_CERT, LOG_ERR, "Refusing LID_CHAINED certificate beyond data size %d", certdatum->size);
*chainlen = 0;
return NULL;
} else if (certlen <= 0) {
- fprintf (stderr, "ERROR: Refusing LID_CHAINED certificate of too-modest data size %d\n", certlen);
+ tlog (TLOG_CERT, LOG_ERR, "Refusing LID_CHAINED certificate of too-modest data size %d", certlen);
*chainlen = 0;
return NULL;
}
// Refuse to disclose client credentials when the server name is unset;
// note that server-claimed identities are unproven during handshake.
if ((lidrole == LID_ROLE_CLIENT) && (*rid == '\0')) {
- fprintf (stderr, "DEBUG: No remote identity (server name) set, so no client credential disclosure\n");
+ tlog (TLOG_USER, LOG_ERR, "No remote identity (server name) set, so no client credential disclosure");
E_g2e ("Missing remote ID",
GNUTLS_E_NO_CERTIFICATE_FOUND);
return gtls_errno;
uint32_t flags;
int lidtype;
- fprintf (stderr, "DEBUG: Found BDB entry %s disclosed to %s\n", creddata.data + 4, (lidrole == LID_ROLE_CLIENT)? rid: "all clients");
+ tlog (TLOG_DB, LOG_DEBUG, "Found BDB entry %s disclosed to %s", creddata.data + 4, (lidrole == LID_ROLE_CLIENT)? rid: "all clients");
ok = dbcred_flags (
&creddata,
&flags);
ok = ok && ((flags & LID_NO_PKCS11) == 0);
ok = ok && (lidtype >= LID_TYPE_MIN);
ok = ok && (lidtype <= LID_TYPE_MAX);
- fprintf (stderr, "DEBUG: BDB entry has flags=0x%08x, so we (%04x/%04x) %s it\n", flags, lidrole, LID_ROLE_MASK, ok? "store": "skip ");
+ tlog (TLOG_DB, LOG_DEBUG, "BDB entry has flags=0x%08x, so we (%04x/%04x) %s it", flags, lidrole, LID_ROLE_MASK, ok? "store": "skip ");
if (ok) {
// Move the credential into the command structure
dbt_store (&creddata,
crs_disclose->close (crs_disclose);
crs_disclose = NULL;
}
-fprintf (stderr, "DEBUG: Returning %d / %s from fetch_local_credentials()\n", gtls_errno, gnutls_strerror (gtls_errno));
return gtls_errno;
}
// uses other name types than exactly one GNUTLS_NAME_DNS.
default:
sni [0] = '\0';
- fprintf (stderr, "Received an unexpected SNI type; that is possible but uncommon; skipping SNI.\n");
+ tlog (TLOG_TLS, LOG_ERR, "Received an unexpected SNI type; that is possible but uncommon; skipping SNI");
break;
}
}
if (sni [0] != '\0') {
if (*lid != '\0') {
if (strncmp (sni, lid, sizeof (sni)) != 0) {
- fprintf (stderr, "Mismatch between client-sent SNI %s and local identity %s\n", sni, lid);
+ tlog (TLOG_USER | TLOG_TLS, LOG_ERR, "Mismatch between client-sent SNI %s and local identity %s", sni, lid);
return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
}
} else {
char **username,
char **password) {
//TODO:FIXED//
- fprintf (stderr, "DEBUG: Picking up SRP credentials\n");
+ tlog (TLOG_CRYPTO, LOG_DEBUG, "DEBUG: Picking up SRP credentials");
*username = strdup ("tester");
*password = strdup ("test");
return GNUTLS_E_SUCCESS;
clisrv_cert_retrieve);
if (gtls_errno == GNUTLS_E_SUCCESS) {
// Setup for certificates
- fprintf (stderr, "DEBUG: Setting client and server certificate credentials\n");
+ tlog (TLOG_CERT, LOG_INFO, "Setting client and server certificate credentials");
cli_creds [cli_credcount].credtp = GNUTLS_CRD_CERTIFICATE;
cli_creds [cli_credcount].cred = (void *) clisrv_certcred;
cli_credcount++;
srv_anoncred,
dh_params);
if (gtls_errno == GNUTLS_E_SUCCESS) {
- fprintf (stderr, "DEBUG: Setting server anonymous credentials\n");
+ tlog (TLOG_CRYPTO, LOG_INFO, "Setting server anonymous credentials");
srv_creds [srv_credcount].credtp = GNUTLS_CRD_ANON;
srv_creds [srv_credcount].cred = (void *) srv_anoncred;
srv_credcount++;
cli_anoncred,
dh_params);
if (gtls_errno == GNUTLS_E_SUCCESS) {
- fprintf (stderr, "DEBUG: Setting client anonymous credentials\n");
+ tlog (TLOG_CRYPTO, LOG_INFO, "Setting client anonymous credentials");
cli_creds [cli_credcount].credtp = GNUTLS_CRD_ANON;
cli_creds [cli_credcount].cred = (void *) cli_anoncred;
cli_credcount++;
"../testdata/tlspool-test-srp.passwd",
"../testdata/tlspool-test-srp.conf"));
if (gtls_errno == GNUTLS_E_SUCCESS) {
- fprintf (stderr, "DEBUG: Setting server SRP credentials\n");
+ tlog (TLOG_CRYPTO, LOG_INFO, "Setting server SRP credentials");
srv_creds [srv_credcount].credtp = GNUTLS_CRD_SRP;
srv_creds [srv_credcount].cred = (void *) srv_srpcred;
srv_credcount++;
cli_srpcred,
cli_srpcreds_retrieve);
if (gtls_errno == GNUTLS_E_SUCCESS) {
- fprintf (stderr, "DEBUG: Setting client SRP credentials\n");
+ tlog (TLOG_CRYPTO, LOG_INFO, "Setting client SRP credentials");
cli_creds [cli_credcount].credtp = GNUTLS_CRD_SRP;
cli_creds [cli_credcount].cred = (void *) cli_srpcred;
cli_credcount++;
//TODO// srv_kdhcred,
//TODO// dh_params));
//TODO// if (gtls_errno == GNUTLS_E_SUCCESS) {
- //TODO// fprintf (stderr, "DEBUG: Setting server KDH credentials\n");
+ //TODO// tlog (TLOG_CRYPTO, LOG_INFO, "Setting server KDH credentials");
//TODO// srv_creds [srv_credcount].credtp = GNUTLS_CRD_KDH;
//TODO// srv_creds [srv_credcount].cred = (void *) srv_kdhcred;
//TODO// srv_credcount++;
//TODO// cli_kdhcred,
//TODO// cli_kdh_retrieve));
//TODO// if (gtls_errno == GNUTLS_E_SUCCESS) {
- //TODO// fprintf (stderr, "DEBUG: Setting client KDH credentials\n");
+ //TODO// tlog (TLOG_CRYPTO, LOG_INFO, "Setting client KDH credentials");
//TODO// cli_creds [cli_credcount].credtp = GNUTLS_CRD_KDH;
//TODO// cli_creds [cli_credcount].cred = (void *) cli_kdhcred;
//TODO// cli_credcount++;
if ((gtls_errno == GNUTLS_E_SUCCESS) &&
( (cli_credcount != EXPECTED_CLI_CREDCOUNT) ||
(srv_credcount != EXPECTED_SRV_CREDCOUNT) ) ) {
- fprintf (stderr, "DEBUG: Not all credential types could be setup (cli %d/%d, srv %d/%d, gtls_errno %d)\n", cli_credcount, EXPECTED_CLI_CREDCOUNT, srv_credcount, EXPECTED_SRV_CREDCOUNT, gtls_errno);
+ tlog (TLOG_CRYPTO, LOG_ERR, "Not all credential types could be setup (cli %d/%d, srv %d/%d, gtls_errno %d)", cli_credcount, EXPECTED_CLI_CREDCOUNT, srv_credcount, EXPECTED_SRV_CREDCOUNT, gtls_errno);
E_g2e ("Not all credentials could be setup",
GNUTLS_E_INSUFFICIENT_CREDENTIALS);
}
gnutls_handshake_set_timeout (session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
}
if (gtls_errno != GNUTLS_E_SUCCESS) {
- fprintf (stderr, "Failed to prepare for TLS: %s\n", gnutls_strerror (gtls_errno));
+ tlog (TLOG_TLS, LOG_ERR, "Failed to prepare for TLS: %s", gnutls_strerror (gtls_errno));
send_error (cmd, EIO, "Failed to prepare for TLS");
close (soxx [0]);
close (soxx [1]);
// Respond to positive or negative outcome of the handshake
if (gtls_errno != GNUTLS_E_SUCCESS) {
gnutls_deinit (session);
- fprintf (stderr, "TLS handshake failed: %s\n", gnutls_strerror (gtls_errno));
+ tlog (TLOG_TLS, LOG_ERR, "TLS handshake failed: %s", gnutls_strerror (gtls_errno));
send_error (cmd, EPERM, "TLS handshake failed");
manage_txn_rollback (&cmd->txn);
close (soxx [0]);
close (passfd);
return;
} else {
- printf ("DEBUG: TLS handshake succeeded over %d\n", passfd);
+ tlog (TLOG_UNIXSOCK | TLOG_TLS, LOG_INFO, "TLS handshake succeeded over %d", passfd);
manage_txn_commit (&cmd->txn);
//TODO// extract_authenticated_remote_identity (cmd);
}
#include <stdlib.h>
#include <string.h>
+
+#include <syslog.h>
#include <errno.h>
#include <gnutls/gnutls.h>
while (more) {
int fnd;
discpatn->size = donai_iterate_memput (discpatn->data, remotesel);
-fprintf (stderr, "DEBUG: Looking up remote selector %.*s\n", discpatn->size, (char *) discpatn->data);
+ tlog (TLOG_DB, LOG_DEBUG, "Looking up remote selector %.*s", discpatn->size, (char *) discpatn->data);
fnd = crs_disclose->get (crs_disclose, discpatn, keydata, DB_SET);
if (fnd == 0) {
// Got the selector pattern!
/* tlspool/manage.c -- Management setup in local databases */
+#include <syslog.h>
#include <errno.h>
#include <sys/stat.h>
DB_TXN *tract = NULL;
if (errno == 0) {
mkdir ("../testdata/tlspool.env", S_IRWXU);
- errno = 0;
+ if (errno == 0) {
+ tlog (TLOG_DB | TLOG_USER, LOG_NOTICE, "Created DB environment directory");
+ } else {
+ // Failure usually indicates the directory exists.
+ // Whatever it was is ignored silently -- as this
+ // friendly mkdir() does not constitute guaranteed
+ // (or even documented) behaviour.
+ errno = 0;
+ }
}
- E_d2ge ("Failed to create DB environment",
+ E_d2ge ("Failed to create DB environment handle",
db_env_create (&dbenv, 0));
E_d2ge ("Failed to open DB environment",
dbenv->open (dbenv, "../testdata/tlspool.env", DB_CREATE | DB_RECOVER | DB_INIT_TXN | DB_INIT_LOG | DB_INIT_LOCK | DB_THREAD | DB_INIT_MPOOL, S_IRUSR | S_IWUSR));
#include <pthread.h>
#include <unistd.h>
+#include <syslog.h>
#include <errno.h>
#include <time.h>
#include <sys/socket.h>
* Connect to the UNIX domain socket for PIN entry
*/
if (strlen (pinsocket) + 1 > sizeof (sun.sun_path)) {
- fprintf (stderr, "Socket path too long: %s\n", pinsocket);
+ tlog (TLOG_UNIXSOCK | TLOG_USER, LOG_CRIT, "Socket path too long: %s", pinsocket);
exit (1);
}
strcpy (sun.sun_path, pinsocket);
bzero (pe->pin, sizeof (pe->pin));
if (pwd) {
if (strlen (pwd) + 1 > sizeof (pe->pin)) {
- fprintf (stderr, "No support for PIN lenghts over 128\n");
+ tlog (TLOG_USER | TLOG_PKCS11, LOG_ERR, "No support for PIN lenghts over 128");
} else {
strcpy (pe->pin, pwd);
}
bzero (pwd, strlen (pwd));
}
- fprintf (stderr, "DEBUG: Offering PIN service to TLS pool with PIN length %d\n", strlen (pe->pin));
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_DEBUG, "Offering PIN service to TLS pool with PIN length %d", strlen (pe->pin));
if (send (sox, &pio, sizeof (pio), 0) != sizeof (pio)) {
pio.pio_cmd = PIOC_ERROR_V1;
pio.pio_data.pioc_error.tlserrno = errno;
strcpy (pio.pio_data.pioc_error.message, "Failed to read full message from TLS pool");
} else {
if ((pio.pio_cmd != PIOC_PINENTRY_V1) && (pio.pio_cmd != PIOC_ERROR_V1)) {
- printf ("DEBUG: Received funny command 0x%08x instead of 0x%08x\n", pio.pio_cmd, PIOC_PINENTRY_V1);
+ tlog (TLOG_UNIXSOCK, LOG_ERR, "Received funny command 0x%08x instead of 0x%08x", pio.pio_cmd, PIOC_PINENTRY_V1);
pio.pio_cmd = PIOC_ERROR_V1;
pio.pio_data.pioc_error.tlserrno = EPROTO;
strcpy (pio.pio_data.pioc_error.message, "Unexpected command response from TLS pool");
perror (pio.pio_data.pioc_error.message);
break;
}
- fprintf (stderr, "DEBUG: Received PIN inquiry from TLS pool\n");
- fprintf (stdout, "Token Manuf: %s\n Model: %s\n Serial: %s\n Label: %s\n Attempt: %d\n", pe->token_manuf, pe->token_model, pe->token_serial, pe->token_label, pe->attempt);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Received PIN inquiry from TLS pool");
+ tlog (TLOG_PKCS11, LOG_INFO, "Token Manuf: %s\n Model: %s\n Serial: %s\n Label: %s\n Attempt: %d", pe->token_manuf, pe->token_model, pe->token_serial, pe->token_label, pe->attempt);
pwd = getpass (pe->prompt);
}
bzero (&pio.pio_data, sizeof (pio.pio_data));
if (pinentry_client == cmd->clientfd) {
// This command came from the same client as last time
pinentry_cmd = cmd;
- printf ("DEBUG: Registered privileged command for PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER | TLOG_UNIXSOCK, LOG_NOTICE, "Registered privileged command for PIN entry");
} else {
// New PIN entry clients await the last one's timeout
time_t now = time (NULL);
// The wait for new client access has passed
pinentry_cmd = cmd;
pinentry_client = cmd->clientfd;
- printf ("DEBUG: Registered new client's command for PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER | TLOG_UNIXSOCK, LOG_NOTICE, "Registered new client's command for PIN entry");
} else {
// The previous client still is privileged
error = 1;
- printf ("DEBUG: Refused PIN entry command from other client\n");
+ tlog (TLOG_PKCS11 | TLOG_USER | TLOG_UNIXSOCK, LOG_NOTICE, "Refused PIN entry command from other client");
}
}
} else {
// There already is a PINENTRY registration
error = 1;
- printf ("DEBUG: Refused extra PIN entry command\n");
+ tlog (TLOG_PKCS11 | TLOG_USER | TLOG_UNIXSOCK, LOG_NOTICE, "Refused extra PIN entry command");
}
pthread_mutex_unlock (&pinentry_lock);
if (error) {
cfgpin = cfg_p11pin ();
if ((cfgpin != NULL) && (*cfgpin) && (strlen (cfgpin) < pin_max)) {
strcpy (pin, cfgpin);
- printf ("DEBUG: Returning configured PIN and OK from PIN entry\n");
+ tlog (TLOG_PKCS11, LOG_DEBUG, "Returning configured PIN and OK from PIN entry");
return 0;
}
//
pthread_mutex_lock (&pinentry_lock);
cmd = pinentry_cmd;
if (cmd != NULL) {
- printf ("DEBUG: Using registered PIN entry command\n");
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_DEBUG, "Using registered PIN entry command");
// A PINENTRY command was registered
pinentry_cmd = NULL;
pinentry_timeout = time (NULL) + cmd->cmd.pio_data.pioc_pinentry.timeout_us / 1000000;
}
pthread_mutex_unlock (&pinentry_lock);
if (retval) {
- printf ("DEBUG: Returning retval from PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_DEBUG, "Returning retval from PIN entry");
return retval;
}
//
// Construct PIN ENTRY response, claim responses and send to the origin
p11kituri = p11_kit_uri_new ();
if (!p11kituri) {
- printf ("DEBUG: Failed to allocate URI for PIN entry\n");
+ tlog (TLOG_PKCS11, LOG_CRIT, "Failed to allocate URI for PIN entry");
return GNUTLS_A_INTERNAL_ERROR;
}
if (p11_kit_uri_parse (token_url, P11_KIT_URI_FOR_TOKEN, p11kituri) != P11_KIT_URI_OK) {
p11_kit_uri_free (p11kituri);
- printf ("DEBUG: Failed to parse URI for PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_ERR, "Failed to parse URI for PIN entry");
return GNUTLS_A_DECODE_ERROR;
}
toktok = p11_kit_uri_get_token_info (p11kituri);
p11_kit_uri_free (p11kituri);
if (!toktok) {
- printf ("DEBUG: Failed to find URI token info for PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_ERR, "Failed to find URI token info for PIN entry");
return GNUTLS_A_DECODE_ERROR;
}
p11cpy (cmd->cmd.pio_data.pioc_pinentry.token_manuf, toktok->manufacturerID, 32);
strcpy (cmd->cmd.pio_data.pioc_pinentry.prompt, "Enter PIN: ");
//
// Await response or timeout
- printf ("DEBUG: Calling send_callback_and_await_response()\n");
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Calling send_callback_and_await_response()");
cmd = send_callback_and_await_response (cmd);
register_pinentry_command (cmd);
- printf ("DEBUG: Returnd send_callback_and_await_response()\n");
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Returnd send_callback_and_await_response()");
if ((cmd->cmd.pio_cmd != PIOC_PINENTRY_V1) || !*cmd->cmd.pio_data.pioc_pinentry.pin) {
- printf ("DEBUG: Funny command or empty PIN code for PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_ERR, "Funny command or empty PIN code for PIN entry");
return GNUTLS_A_USER_CANCELED;
}
if (1 + strlen (cmd->cmd.pio_data.pioc_pinentry.pin) > pin_max) {
- printf ("DEBUG: PIN too long for PIN entry\n");
+ tlog (TLOG_PKCS11 | TLOG_USER, LOG_ERR, "PIN too long for PIN entry");
return GNUTLS_A_RECORD_OVERFLOW;
}
strcpy (pin, cmd->cmd.pio_data.pioc_pinentry.pin);
bzero (cmd->cmd.pio_data.pioc_pinentry.pin, sizeof (cmd->cmd.pio_data.pioc_pinentry.pin));
- printf ("DEBUG: Returning entered PIN and OK from PIN entry\n");
+ tlog (TLOG_PKCS11, LOG_DEBUG, "Returning entered PIN and OK from PIN entry");
return 0;
}
#include <errno.h>
#include <pthread.h>
+#include <syslog.h>
#include <fcntl.h>
#include <poll.h>
if (!cmdpool) {
cmdpool = (struct command *) calloc (1000, sizeof (struct command));
if (!cmdpool) {
- fprintf (stderr, "Failed to allocate command pool\n");
+ tlog (TLOG_UNIXSOCK, LOG_CRIT, "Failed to allocate command pool");
exit (1);
}
bzero (cmdpool, 1000 * sizeof (struct command));
//TODO// soxinfo = calloc ()
//TODO// }
if (num_sox == 1024) {
- fprintf (stderr, "Cannot allocate more than 1024 server sockets\n");
+ tlog (TLOG_UNIXSOCK, LOG_CRIT, "Cannot allocate more than 1024 server sockets");
exit (1);
}
soxpoll [num_sox].fd = sox;
* (int *) CMSG_DATA (cmsg) = passfd;
}
- printf ("DEBUG: Sending command 0x%08x and fd %d to socket %d\n", cmd->cmd.pio_cmd, passfd, cmd->clientfd);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Sending command 0x%08x and fd %d to socket %d", cmd->cmd.pio_cmd, passfd, cmd->clientfd);
if (sendmsg (cmd->clientfd, &mh, 0) == -1) {
//TODO// Differentiate behaviour based on errno?
perror ("Failed to send command");
cmd->claimed = 0;
return 0;
} else {
- printf ("DEBUG: Sent command code 0x%08x\n", cmd->cmd.pio_cmd);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Sent command code 0x%08x", cmd->cmd.pio_cmd);
cmd->claimed = 0;
return 1;
}
perror ("Failed to receive command");
return 0;
}
- printf ("DEBUG: Received command request code 0x%08x with cbid=%d over fd=%d\n", cmd->cmd.pio_cmd, cmd->cmd.pio_cbid, sox);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Received command request code 0x%08x with cbid=%d over fd=%d", cmd->cmd.pio_cmd, cmd->cmd.pio_cbid, sox);
cmsg = CMSG_FIRSTHDR (&mh);
if (cmsg && (cmsg->cmsg_len == CMSG_LEN (sizeof (int)))) {
if ((cmsg->cmsg_level == SOL_SOCKET) && (cmsg->cmsg_type == SCM_RIGHTS)) {
cmd->passfd = * (int *) CMSG_DATA (cmsg);
- printf ("DEBUG: Received file descriptor as %d\n", cmd->passfd);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Received file descriptor as %d", cmd->passfd);
}
}
cb = cbfree;
if (!cb) {
//TODO// Allocate more...
- fprintf (stderr, "Ran out of callback structures. Crashing as a coward\n");
+ tlog (TLOG_UNIXSOCK, LOG_CRIT, "Ran out of callback structures. Crashing as a coward");
exit (1);
}
//TODO// It's simpler to administer index numbers and not pointers
send_command (cmdresp, -1);
do {
//TODO// pthread_cond_timedwait?
- printf ("DEBUG: Waiting with fd=%d and cbid=%d on semaphone 0x%08x\n", cb->fd, cmdresp->cmd.pio_cbid, cb);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Waiting with fd=%d and cbid=%d on semaphone 0x%08x", cb->fd, cmdresp->cmd.pio_cbid, cb);
pthread_cond_wait (&cb->semaphore, &cbfree_mutex);
followup = cb->followup;
} while (!followup);
cblist [cbid].fd = -1;
cblist [cbid].followup = cmd;
pthread_mutex_lock (&cbfree_mutex);
- printf ("DEBUG: Signaling on the semaphore of callback 0x%08x\n", &cblist [cbid]);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Signaling on the semaphore of callback 0x%08x", &cblist [cbid]);
pthread_cond_signal (&cblist [cbid].semaphore);
pthread_mutex_unlock (&cbfree_mutex);
}
/* Process a command packet that entered on a TLS pool socket
*/
static void process_command (struct command *cmd) {
- printf ("DEBUG: Processing command 0x%08x\n", cmd->cmd.pio_cmd);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Processing command 0x%08x", cmd->cmd.pio_cmd);
union pio_data *d = &cmd->cmd.pio_data;
if (is_callback (cmd)) {
post_callback (cmd);
void process_activity (int sox, int soxidx, struct soxinfo *soxi, short int revents) {
if (revents & POLLOUT) {
//TODO// signal waiting thread that it may continue
- printf ("DEBUG: Eekk!! Could send a packet?!? Unregistering client\n");
+ tlog (TLOG_UNIXSOCK, LOG_CRIT, "Eekk!! Could send a packet?!? Unregistering client");
unregister_client_socket_byindex (soxidx);
close (sox);
}
socklen_t salen = sizeof (sa);
int newsox = accept (sox, &sa, &salen);
if (newsox != -1) {
- printf ("DEBUG: Received incoming connection. Registering it.\n");
+ tlog (TLOG_UNIXSOCK, LOG_NOTICE, "Received incoming connection. Registering it");
register_client_socket (newsox);
}
}
if (receive_command (sox, cmd)) {
process_command (cmd);
} else {
- printf ("DEBUG: Failed to receive command request\n");
+ tlog (TLOG_UNIXSOCK, LOG_ERR, "Failed to receive command request");
}
}
}
*/
void hangup_service (void) {
stop_service = 1;
- fprintf (stderr, "DEBUG: Requested service to hangup soon\n");
+ tlog (TLOG_UNIXSOCK, LOG_NOTICE, "Requested service to hangup soon");
}
/* The main service loop. It uses poll() to find things to act upon. */
cbfree = NULL;
errno = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
if (errno) {
- fprintf (stderr, "Service routine thread cancellability refused\n");
+ tlog (TLOG_UNIXSOCK | TLOG_DAEMON, LOG_ERR, "Service routine thread cancellability refused");
exit (1);
}
for (i=0; i<1024; i++) {
cblist [i].followup = NULL;
cbfree = &cblist [i];
}
- printf ("DEBUG: Polling %d sockets numbered %d, %d, %d, ...\n", num_sox, soxpoll [0].fd, soxpoll [1].fd, soxpoll [2].fd);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Polling %d sockets numbered %d, %d, %d, ...", num_sox, soxpoll [0].fd, soxpoll [1].fd, soxpoll [2].fd);
while (polled = poll (soxpoll, num_sox, -1), polled > 0) {
- printf ("DEBUG: Polled %d sockets, returned %d\n", num_sox, polled);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Polled %d sockets, returned %d", num_sox, polled);
for (i=0; i<num_sox; i++) {
if (soxpoll [i].revents & (POLLHUP|POLLERR|POLLNVAL)) {
int sox = soxpoll [i].fd;
- printf ("DEBUG: Unregistering socket %d\n", sox);
+ tlog (TLOG_UNIXSOCK, LOG_NOTICE, "Unregistering socket %d", sox);
unregister_client_socket_byindex (i);
close (sox);
continue;
} else if (soxpoll [i].revents) {
- printf ("DEBUG: Socket %d has revents=%d\n", soxpoll [i].fd, soxpoll [i].revents);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Socket %d has revents=%d", soxpoll [i].fd, soxpoll [i].revents);
process_activity (soxpoll [i].fd, i, &soxinfo [i], soxpoll [i].revents);
}
}
- fprintf (stderr, "DEBUG: Polling %d sockets numbered %d, %d, %d, ...\n", num_sox, soxpoll [0].fd, soxpoll [1].fd, soxpoll [2].fd);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Polling %d sockets numbered %d, %d, %d, ...", num_sox, soxpoll [0].fd, soxpoll [1].fd, soxpoll [2].fd);
}
if (stop_service) {
- fprintf (stderr, "DEBUG: Service hangup in response to request\n");
+ tlog (TLOG_UNIXSOCK, LOG_NOTICE, "Service hangup in response to request");
} else {
- fprintf (stderr, "DEBUG: Polled %d sockets, returned %d\n", num_sox, polled);
+ tlog (TLOG_UNIXSOCK, LOG_DEBUG, "Polled %d sockets, returned %d", num_sox, polled);
perror ("Failed to poll for activity");
}
}