summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/roadmap.rst6
-rw-r--r--ncserver/base/log.py4
-rw-r--r--ncserver/server.py31
3 files changed, 35 insertions, 6 deletions
diff --git a/doc/roadmap.rst b/doc/roadmap.rst
index 8cc3670..ff46745 100644
--- a/doc/roadmap.rst
+++ b/doc/roadmap.rst
@@ -69,13 +69,13 @@ Resolved TBDs
* [/] Event logging
- * [ ] auth
+ * [/] auth
* [ ] Connection established
- * [ ] Authentication succeess
+ * [X] Authentication succeess
- * [ ] Authentication failure
+ * [X] Authentication failure
* [ ] Connection closed
diff --git a/ncserver/base/log.py b/ncserver/base/log.py
index 053baec..af8c105 100644
--- a/ncserver/base/log.py
+++ b/ncserver/base/log.py
@@ -61,10 +61,12 @@ if not hasattr(logging, 'NOTICE'):
logging.NOTICE = 25
def log_notice(self, message, *args, **kwargs):
+ """Log a NOTICE message."""
if self.isEnabledFor(25):
- self._log(25, message, args, **kwargs)
+ self._log(25, message, args, **kwargs) # pylint: disable=W0212
logging.getLoggerClass().notice = log_notice
def root_notice(message, *args, **kwargs):
+ """Log a NOTICE message."""
logging.log(25, message, *args, **kwargs)
logging.notice = root_notice
diff --git a/ncserver/server.py b/ncserver/server.py
index dd35b2d..3945a99 100644
--- a/ncserver/server.py
+++ b/ncserver/server.py
@@ -14,10 +14,13 @@ import logging
from lxml import etree
+import netconf.base
+import paramiko
+
from netconf import error, util
from netconf.server import NetconfSSHServer, SSHAuthorizedKeysController
-from ncserver.base.log import configure_logging, LOG_CONFIG
+from ncserver.base.log import configure_logging, LOG_AUTH, LOG_CONFIG
from ncserver.base.modman import ModuleManager
from ncserver.base.util import user_for_session
from ncserver.config import ConfigManager
@@ -33,6 +36,30 @@ def log_read(session, rpc):
)
+class AuthenticationController(SSHAuthorizedKeysController):
+ """Authentication controller that logs failures."""
+ def check_auth_publickey(self, username, key):
+ result = super().check_auth_publickey(username, key)
+ if result == paramiko.AUTH_FAILED:
+ LOG_AUTH.error('Authentication failed for %s', username)
+ return result
+
+
+_open_session = getattr(netconf.base.NetconfSession, '_open_session')
+def _open_session_and_log(self, is_server):
+ """Log that authentication has been successful."""
+ _open_session(self, is_server)
+ peername = self.pkt_stream.stream.getpeername()
+ ipaddr = peername[0]
+ port = peername[1]
+ if ':' in ipaddr:
+ ipaddr = '[' + ipaddr + ']'
+ LOG_AUTH.notice('Authentication granted to %s from %s:%d, session %d',
+ user_for_session(self), ipaddr, port, self.session_id
+ )
+setattr(netconf.base.NetconfSession, '_open_session', _open_session_and_log)
+
+
class Server:
"""The NETCONF server component."""
@@ -43,7 +70,7 @@ class Server:
The port number to listen on. Typically 830.
"""
self.config = ConfigManager()
- self.auth = SSHAuthorizedKeysController(
+ self.auth = AuthenticationController(
users=self.config.get_list('server', 'users')
)