From 1d092172ee12db7f2f525d80588cccc30157749b 2011-08-16 01:34:09 From: Fernando Perez Date: 2011-08-16 01:34:09 Subject: [PATCH] Merge pull request #689 from minrk/auth Protect ipkernel from bad messages: now the kernel logs bad messages as errors instead of crashing. --- diff --git a/IPython/zmq/ipkernel.py b/IPython/zmq/ipkernel.py index 1d130ea..bbd6833 100755 --- a/IPython/zmq/ipkernel.py +++ b/IPython/zmq/ipkernel.py @@ -121,7 +121,11 @@ class Kernel(Configurable): def do_one_iteration(self): """Do one iteration of the kernel's evaluation loop. """ - ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK) + try: + ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK) + except Exception: + self.log.warn("Invalid Message:", exc_info=True) + return if msg is None: return @@ -375,7 +379,11 @@ class Kernel(Configurable): def _abort_queue(self): while True: - ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK) + try: + ident,msg = self.session.recv(self.shell_socket, zmq.NOBLOCK) + except Exception: + self.log.warn("Invalid Message:", exc_info=True) + continue if msg is None: break else: @@ -402,7 +410,13 @@ class Kernel(Configurable): msg = self.session.send(self.stdin_socket, u'input_request', content, parent) # Await a response. - ident, reply = self.session.recv(self.stdin_socket, 0) + while True: + try: + ident, reply = self.session.recv(self.stdin_socket, 0) + except Exception: + self.log.warn("Invalid Message:", exc_info=True) + else: + break try: value = reply['content']['value'] except: diff --git a/IPython/zmq/session.py b/IPython/zmq/session.py index 98a573a..bee9396 100644 --- a/IPython/zmq/session.py +++ b/IPython/zmq/session.py @@ -588,7 +588,6 @@ class Session(Configurable): try: return idents, self.unserialize(msg_list, content=content, copy=copy) except Exception as e: - print (idents, msg_list) # TODO: handle it raise e @@ -661,6 +660,8 @@ class Session(Configurable): msg_list[i] = msg_list[i].bytes if self.auth is not None: signature = msg_list[0] + if not signature: + raise ValueError("Unsigned Message") if signature in self.digest_history: raise ValueError("Duplicate Signature: %r"%signature) self.digest_history.add(signature) diff --git a/docs/source/parallel/parallel_security.txt b/docs/source/parallel/parallel_security.txt index 7b96a93..49f78b7 100644 --- a/docs/source/parallel/parallel_security.txt +++ b/docs/source/parallel/parallel_security.txt @@ -132,11 +132,10 @@ owner, just as is common practice with a user's keys in their `.ssh` directory. .. warning:: - It is important to note that the key authentication, as emphasized by the use of - a uuid rather than generating a key with a cryptographic library, provides a - defense against *accidental* messages more than it does against malicious attacks. - If loopback is compromised, it would be trivial for an attacker to intercept messages - and deduce the key, as there is no encryption. + It is important to note that the signatures protect against unauthorized messages, + but, as there is no encryption, provide exactly no protection of data privacy. It is + possible, however, to use a custom serialization scheme (via Session.packer/unpacker + traits) that does incorporate your own encryption scheme.