From 2cb424c6464be24045c9f41b66811c3992970189 Mon Sep 17 00:00:00 2001
From: Yves Rutschle <yves.rutschle@mdal.fr>
Date: Tue, 15 Dec 2015 15:51:18 +0100
Subject: [PATCH] Added log_level option to configuration file, which switches
 off log at each connection

---
 ChangeLog   |  3 +++
 basic.cfg   |  2 +-
 common.c    |  3 +++
 example.cfg |  4 ++--
 probe.c     | 20 ++++++++++----------
 probe.h     |  3 +++
 sslh-main.c |  7 ++++++-
 7 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 05ccaa5..3262f78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,9 @@ vNEXT:
 	no longer required, 'name' field can now contain
 	'sni' or 'regex', with corresponding options (see
 	example.org)
+	Added 'log_level' option to each protocol, which
+	allows to turn off generation of log at each
+	connection.
 
 v1.17: 	09MAR2015
 	Support RFC5952-style IPv6 addresses, e.g. [::]:443.
diff --git a/basic.cfg b/basic.cfg
index 64942e5..2f8252c 100644
--- a/basic.cfg
+++ b/basic.cfg
@@ -23,7 +23,7 @@ protocols:
      { name: "openvpn"; host: "localhost"; port: "1194"; },
      { name: "xmpp"; host: "localhost"; port: "5222"; },
      { name: "http"; host: "localhost"; port: "80"; },
-     { name: "ssl"; host: "localhost"; port: "443"; },
+     { name: "ssl"; host: "localhost"; port: "443"; log_level: 0; },
      { name: "anyprot"; host: "localhost"; port: "443"; }
 );
 
diff --git a/common.c b/common.c
index 0120047..218bd91 100644
--- a/common.c
+++ b/common.c
@@ -431,6 +431,9 @@ void log_connection(struct connection *cnx)
         local[MAX_NAMELENGTH], target[MAX_NAMELENGTH];
     int res;
 
+    if (cnx->proto->log_level < 1)
+        return;
+
     addr.ai_addr = (struct sockaddr*)&ss;
     addr.ai_addrlen = sizeof(ss);
 
diff --git a/example.cfg b/example.cfg
index 5ca9af6..91f0f36 100644
--- a/example.cfg
+++ b/example.cfg
@@ -46,8 +46,8 @@ protocols:
      { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; },
      { name: "http"; host: "localhost"; port: "80"; },
 
-     { name: "sni"; host: "localhost"; port: "993"; sni_hostnames: [ "mail.rutschle.net", "mail.englishintoulouse.com" ]; },
-     { name: "sni"; host: "localhost"; port: "xmpp-client"; sni_hostnames: [ "im.rutschle.net", "im.englishintoulouse.com" ]; },
+     { name: "sni"; host: "localhost"; port: "993"; sni_hostnames: [ "mail.rutschle.net", "mail.englishintoulouse.com" ]; log_level: 0; },
+     { name: "sni"; host: "localhost"; port: "xmpp-client"; sni_hostnames: [ "im.rutschle.net", "im.englishintoulouse.com" ];  log_level: 0;},
 
 # OpenVPN
      { name: "regex"; host: "localhost"; port: "1194"; regex_patterns: [ "^\x00[\x0D-\xFF]$", "^\x00[\x0D-\xFF]\x38" ]; },
diff --git a/probe.c b/probe.c
index 27120c4..73be132 100644
--- a/probe.c
+++ b/probe.c
@@ -41,16 +41,16 @@ static int is_true(const char *p, int len, struct proto* proto) { return 1; }
 /* Table of protocols that have a built-in probe
  */
 static struct proto builtins[] = {
-    /* description   service  saddr   probe  */
-    { "ssh",         "sshd",   NULL,   is_ssh_protocol},
-    { "openvpn",     NULL,     NULL,   is_openvpn_protocol },
-    { "tinc",        NULL,     NULL,   is_tinc_protocol },
-    { "xmpp",        NULL,     NULL,   is_xmpp_protocol },
-    { "http",        NULL,     NULL,   is_http_protocol },
-    { "ssl",         NULL,     NULL,   is_tls_protocol },
-    { "tls",         NULL,     NULL,   is_tls_protocol },
-    { "adb",         NULL,     NULL,   is_adb_protocol },
-    { "anyprot",     NULL,     NULL,   is_true }
+    /* description   service  saddr  log_level   probe  */
+    { "ssh",         "sshd",   NULL,  1,         is_ssh_protocol},
+    { "openvpn",     NULL,     NULL,  1,         is_openvpn_protocol },
+    { "tinc",        NULL,     NULL,  1,         is_tinc_protocol },
+    { "xmpp",        NULL,     NULL,  1,         is_xmpp_protocol },
+    { "http",        NULL,     NULL,  1,         is_http_protocol },
+    { "ssl",         NULL,     NULL,  1,         is_tls_protocol },
+    { "tls",         NULL,     NULL,  1,         is_tls_protocol },
+    { "adb",         NULL,     NULL,  1,         is_adb_protocol },
+    { "anyprot",     NULL,     NULL,  1,         is_true }
 };
 
 static struct proto *protocols;
diff --git a/probe.h b/probe.h
index 81ac684..0a663fb 100644
--- a/probe.h
+++ b/probe.h
@@ -20,6 +20,9 @@ struct proto {
     const char* description;  /* a string that says what it is (for logging and command-line parsing) */
     const char* service;      /* service name to do libwrap checks */
     struct addrinfo *saddr; /* list of addresses to try and switch that protocol */
+    int log_level;  /* 0: No logging of connection
+                     * 1: Log incoming connection
+                     */
 
     /* function to probe that protocol; parameters are buffer and length
      * containing the data to probe, and a pointer to the protocol structure */
diff --git a/sslh-main.c b/sslh-main.c
index 0025017..e35bfd9 100644
--- a/sslh-main.c
+++ b/sslh-main.c
@@ -119,10 +119,11 @@ static void printsettings(void)
     
     for (p = get_first_protocol(); p; p = p->next) {
         fprintf(stderr,
-                "%s addr: %s. libwrap service: %s family %d %d\n", 
+                "%s addr: %s. libwrap service: %s log_level: %d family %d %d\n", 
                 p->description, 
                 sprintaddr(buf, sizeof(buf), p->saddr), 
                 p->service,
+                p->log_level,
                 p->saddr->ai_family,
                 p->saddr->ai_addr->sa_family);
     }
@@ -271,6 +272,10 @@ static int config_protocols(config_t *config, struct proto **prots)
                 p->description = name;
                 config_setting_lookup_string(prot, "service", &(p->service));
 
+                if (config_setting_lookup_int(prot, "log_level", &p->log_level) == CONFIG_FALSE) {
+                    p->log_level = 1;
+                }
+
                 resolve_split_name(&(p->saddr), hostname, port);
 
                 p->probe = get_probe(name);