Switched to syslog() for errors and notifications
authorRick van Rein <rick@openfortress.nl>
Fri, 23 Jan 2015 16:30:32 +0000 (16:30 +0000)
committerRick van Rein <rick@openfortress.nl>
Fri, 23 Jan 2015 16:30:32 +0000 (16:30 +0000)
* Config file options: log_level, log_mask, log_stderr

TODO
etc/tlspool.conf
include/tlspool/internal.h
src/config.c
src/daemon.c
src/error.c [new file with mode: 0644]
src/handler.c
src/localid.c
src/manage.c
src/pinentry.c
src/service.c

diff --git a/TODO b/TODO
index e0a3998..0fd3e33 100644 (file)
--- a/TODO
+++ b/TODO
@@ -17,4 +17,4 @@ There are many ways in which the current TLS Pool can be improved:
 - 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()
index 5c40f5e..984b2d4 100644 (file)
@@ -1,4 +1,4 @@
-# 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
@@ -34,7 +34,7 @@ socket_mode 0660
 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.
@@ -46,7 +46,42 @@ daemon_user tlspool
 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
@@ -68,7 +103,7 @@ daemon_group tlspool
 # 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
@@ -99,7 +134,7 @@ pkcs11_pin 1234
 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.
 #
@@ -110,7 +145,7 @@ ldap_proxy ldap://[2001:db8::389:1]
 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.
@@ -148,7 +183,7 @@ privacy_attempt no
 
 #
 # 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
index aaf6132..70fd449 100644 (file)
@@ -102,6 +102,10 @@ int ldap_fetch_openpgp_cert (gnutls_openpgp_crt_t *pgpcrtdata, char *localid);
 
 /* 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.
  *
@@ -122,6 +126,8 @@ char *cfg_p11pin (void);
  * 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;
 
@@ -166,4 +172,25 @@ 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
index 76f3448..d182ed5 100644 (file)
@@ -12,6 +12,7 @@
 #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;
@@ -52,6 +56,9 @@ enum VARS {
        CFGVAR_RADIUS_AUTHN,
        CFGVAR_RADIUS_AUTHZ,
        CFGVAR_RADIUS_ACCT,
+       CFGVAR_LOG_LEVEL,
+       CFGVAR_LOG_FILTER,
+       CFGVAR_LOG_STDERR,
        //
        CFGVAR_LENGTH,
        CFGVAR_NONE = -1
@@ -88,11 +95,97 @@ struct cfgopt config_options [] = {
        "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");
@@ -185,7 +278,9 @@ void cfg_setvar (char *item, int itemno, char *value) {
                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) {
@@ -307,7 +402,9 @@ void cfg_socketname (char *item, int itemno, char *value) {
 }
 
 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);
@@ -317,7 +414,9 @@ void cfg_user (char *item, int itemno, char *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);
@@ -333,6 +432,18 @@ void cfg_chroot (char *item, int itemno, char *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) {
@@ -343,7 +454,9 @@ static void free_p11pin (void) {
 }
 
 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 ();
 }
@@ -351,7 +464,9 @@ void cfg_p11path (char *item, int itemno, char *value) {
 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);
@@ -361,7 +476,9 @@ void cfg_p11token (char *item, int itemno, char *value) {
                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++;
index 35fb09e..6c31700 100644 (file)
@@ -6,10 +6,16 @@
 #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 ();
 }
 
@@ -89,17 +95,20 @@ int main (int argc, char *argv []) {
                                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;
                }
        }
diff --git a/src/error.c b/src/error.c
new file mode 100644 (file)
index 0000000..c94fa20
--- /dev/null
@@ -0,0 +1,338 @@
+/* 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;
+}
index 0fd642e..6a3fa0c 100644 (file)
@@ -9,6 +9,7 @@
 #include <alloca.h>
 
 #include <unistd.h>
+#include <syslog.h>
 #include <errno.h>
 #include <poll.h>
 
@@ -138,7 +139,7 @@ static gtls_error load_dh_params (void) {
                // 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;
@@ -157,7 +158,7 @@ static gtls_error load_dh_params (void) {
                        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 ();
                }
@@ -187,7 +188,7 @@ static void remove_dh_params (void) {
 /* 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);
 }
 
 
@@ -199,22 +200,21 @@ void setup_handler (void) {
        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",
@@ -224,16 +224,16 @@ fprintf (stderr, "Now errno=%d, gtls_errno=%d\n", errno, gtls_errno);
        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);
        }
 }
@@ -285,18 +285,18 @@ static void copycat (int local, int remote, gnutls_session_t wrapped, int master
        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;
@@ -304,22 +304,22 @@ static void copycat (int local, int remote, gnutls_session_t wrapped, int master
                                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;
@@ -329,17 +329,17 @@ static void copycat (int local, int remote, gnutls_session_t wrapped, int master
                        } 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);
 }
 
 
@@ -413,7 +413,7 @@ gtls_error clisrv_cert_retrieve (gnutls_session_t session,
                }
                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;
@@ -428,14 +428,14 @@ gtls_error clisrv_cert_retrieve (gnutls_session_t session,
        // 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;
@@ -447,11 +447,11 @@ gtls_error clisrv_cert_retrieve (gnutls_session_t session,
        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;
                }
@@ -491,7 +491,7 @@ gtls_error clisrv_cert_retrieve (gnutls_session_t session,
                &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;
@@ -552,7 +552,7 @@ gtls_error clisrv_cert_retrieve (gnutls_session_t session,
 
        //
        // 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;
 }
 
@@ -648,13 +648,13 @@ gnutls_pcert_st *load_certificate_chain (uint32_t flags, unsigned int *chainlen,
                        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;
                }
@@ -748,7 +748,7 @@ gtls_error fetch_local_credentials (struct command *cmd) {
        // 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;
@@ -814,7 +814,7 @@ gtls_error fetch_local_credentials (struct command *cmd) {
                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);
@@ -823,7 +823,7 @@ gtls_error fetch_local_credentials (struct command *cmd) {
                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,
@@ -849,7 +849,6 @@ gtls_error fetch_local_credentials (struct command *cmd) {
                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;
 }
 
@@ -890,14 +889,14 @@ int srv_clienthello (gnutls_session_t session) {
                // 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 {
@@ -921,7 +920,7 @@ int cli_srpcreds_retrieve (gnutls_session_t session,
                                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;
@@ -968,7 +967,7 @@ int setup_handler_credentials (void) {
                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++;
@@ -990,7 +989,7 @@ int setup_handler_credentials (void) {
                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++;
@@ -1010,7 +1009,7 @@ int setup_handler_credentials (void) {
                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++;
@@ -1032,7 +1031,7 @@ int setup_handler_credentials (void) {
                        "../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++;
@@ -1051,7 +1050,7 @@ int setup_handler_credentials (void) {
                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++;
@@ -1071,7 +1070,7 @@ int setup_handler_credentials (void) {
        //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++;
@@ -1091,7 +1090,7 @@ int setup_handler_credentials (void) {
        //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++;
@@ -1106,7 +1105,7 @@ int setup_handler_credentials (void) {
        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);
        }
@@ -1344,7 +1343,7 @@ static void *starttls_thread (void *cmd_void) {
                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]);
@@ -1386,7 +1385,7 @@ static void *starttls_thread (void *cmd_void) {
        // 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]);
@@ -1394,7 +1393,7 @@ static void *starttls_thread (void *cmd_void) {
                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);
        }
index 83fdc60..6ab65bd 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <stdlib.h>
 #include <string.h>
+
+#include <syslog.h>
 #include <errno.h>
 
 #include <gnutls/gnutls.h>
@@ -132,7 +134,7 @@ gtls_error dbcred_iterate_from_remoteid_selector (DBC *crs_disclose, DBC *crs_lo
        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!
index addf2ba..92c405c 100644 (file)
@@ -1,6 +1,7 @@
 /* tlspool/manage.c -- Management setup in local databases */
 
 
+#include <syslog.h>
 #include <errno.h>
 
 #include <sys/stat.h>
@@ -88,9 +89,17 @@ gtls_error setup_management (void) {
        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));
index dddfcb3..fa82ed1 100644 (file)
@@ -7,6 +7,7 @@
 #include <pthread.h>
 
 #include <unistd.h>
+#include <syslog.h>
 #include <errno.h>
 #include <time.h>
 #include <sys/socket.h>
@@ -47,7 +48,7 @@ void enter_pins (char *pinsocket) {
         * 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);
@@ -76,13 +77,13 @@ void enter_pins (char *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;
@@ -94,7 +95,7 @@ void enter_pins (char *pinsocket) {
                                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");
@@ -106,8 +107,8 @@ void enter_pins (char *pinsocket) {
                        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));
@@ -161,7 +162,7 @@ void register_pinentry_command (struct command *cmd) {
                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);
@@ -169,17 +170,17 @@ void register_pinentry_command (struct command *cmd) {
                                // 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) {
@@ -257,7 +258,7 @@ int gnutls_pin_callback (void *userdata,
        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;
        }
        //
@@ -265,7 +266,7 @@ int gnutls_pin_callback (void *userdata,
        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;
@@ -276,25 +277,25 @@ int gnutls_pin_callback (void *userdata,
        }
        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);
@@ -305,21 +306,21 @@ int gnutls_pin_callback (void *userdata,
        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;
 }
 
index c862c55..16c3b8a 100644 (file)
@@ -7,6 +7,7 @@
 #include <errno.h>
 #include <pthread.h>
 
+#include <syslog.h>
 #include <fcntl.h>
 #include <poll.h>
 
@@ -87,7 +88,7 @@ static struct command *allocate_command_for_clientfd (int fd) {
        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));
@@ -140,7 +141,7 @@ void register_socket (int sox, uint32_t soxinfo_flags) {
        //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;
@@ -200,14 +201,14 @@ int send_command (struct command *cmd, int passfd) {
                * (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;
        }
@@ -250,13 +251,13 @@ int receive_command (int sox, struct command *cmd) {
                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);
                }
        }
 
@@ -305,7 +306,7 @@ struct command *send_callback_and_await_response (struct command *cmdresp) {
        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
@@ -317,7 +318,7 @@ struct command *send_callback_and_await_response (struct command *cmdresp) {
        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);
@@ -338,7 +339,7 @@ static void post_callback (struct command *cmd) {
        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);
 }
@@ -347,7 +348,7 @@ static void post_callback (struct command *cmd) {
 /* 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);
@@ -382,7 +383,7 @@ static void process_command (struct command *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);
        }
@@ -392,7 +393,7 @@ void process_activity (int sox, int soxidx, struct soxinfo *soxi, short int reve
                        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);
                        }
                }
@@ -401,7 +402,7 @@ void process_activity (int sox, int soxidx, struct soxinfo *soxi, short int reve
                        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");
                        }
                }
        }
@@ -411,7 +412,7 @@ void process_activity (int sox, int soxidx, struct soxinfo *soxi, short int reve
  */
 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. */
@@ -421,7 +422,7 @@ void run_service (void) {
        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++) {
@@ -431,27 +432,27 @@ void run_service (void) {
                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");
        }
 }