From 478a802691f4e49f3ee21537c39b64f4fbb994bc 2015-02-28 20:59:14 From: Matthias Bussonnier Date: 2015-02-28 20:59:14 Subject: [PATCH] Merge pull request #7832 from minrk/default-secure-session remove default_secure, make Session secure by default --- diff --git a/IPython/consoleapp.py b/IPython/consoleapp.py index 83c5e8e..2827527 100644 --- a/IPython/consoleapp.py +++ b/IPython/consoleapp.py @@ -30,7 +30,7 @@ from IPython.kernel.zmq.kernelapp import ( IPKernelApp ) from IPython.kernel.zmq.pylab.config import InlineBackend -from IPython.kernel.zmq.session import Session, default_secure +from IPython.kernel.zmq.session import Session from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell from IPython.kernel.connect import ConnectionFileMixin @@ -338,7 +338,6 @@ class IPythonConsoleApp(ConnectionFileMixin): IPythonConsoleApp.initialize(self,argv) """ self.init_connection_file() - default_secure(self.config) self.init_ssh() self.init_kernel_manager() self.init_kernel_client() diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py index 536aee5..d1ed2d7 100644 --- a/IPython/html/notebookapp.py +++ b/IPython/html/notebookapp.py @@ -77,7 +77,7 @@ from IPython.core.application import ( from IPython.core.profiledir import ProfileDir from IPython.kernel import KernelManager from IPython.kernel.kernelspec import KernelSpecManager -from IPython.kernel.zmq.session import default_secure, Session +from IPython.kernel.zmq.session import Session from IPython.nbformat.sign import NotebookNotary from IPython.utils.importstring import import_item from IPython.utils import submodule @@ -764,9 +764,6 @@ class NotebookApp(BaseIPythonApplication): self.ipython_kernel_argv = ["--profile-dir", self.profile_dir.location] def init_configurables(self): - # force Session default to be secure - default_secure(self.config) - self.kernel_spec_manager = self.kernel_spec_manager_class( parent=self, ipython_dir=self.ipython_dir, diff --git a/IPython/html/services/kernels/handlers.py b/IPython/html/services/kernels/handlers.py index b21b3cc..14390ac 100644 --- a/IPython/html/services/kernels/handlers.py +++ b/IPython/html/services/kernels/handlers.py @@ -179,6 +179,8 @@ class ZMQChannelsHandler(AuthenticatedZMQStreamHandler): # then request kernel info, waiting up to a certain time before giving up. # We don't want to wait forever, because browsers don't take it well when # servers never respond to websocket connection requests. + kernel = self.kernel_manager.get_kernel(self.kernel_id) + self.session.key = kernel.session.key future = self.request_kernel_info() def give_up(): diff --git a/IPython/kernel/inprocess/ipkernel.py b/IPython/kernel/inprocess/ipkernel.py index 8086afa..f524561 100644 --- a/IPython/kernel/inprocess/ipkernel.py +++ b/IPython/kernel/inprocess/ipkernel.py @@ -124,7 +124,7 @@ class InProcessKernel(IPythonKernel): def _session_default(self): from IPython.kernel.zmq.session import Session - return Session(parent=self) + return Session(parent=self, key=b'') def _shell_class_default(self): return InProcessInteractiveShell diff --git a/IPython/kernel/inprocess/manager.py b/IPython/kernel/inprocess/manager.py index db833ea..9e90d75 100644 --- a/IPython/kernel/inprocess/manager.py +++ b/IPython/kernel/inprocess/manager.py @@ -1,23 +1,13 @@ """A kernel manager for in-process kernels.""" -#----------------------------------------------------------------------------- -# Copyright (C) 2013 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. from IPython.utils.traitlets import Instance, DottedObjectName from IPython.kernel.managerabc import KernelManagerABC from IPython.kernel.manager import KernelManager +from IPython.kernel.zmq.session import Session -#----------------------------------------------------------------------------- -# Main kernel manager class -#----------------------------------------------------------------------------- class InProcessKernelManager(KernelManager): """A manager for an in-process kernel. @@ -33,14 +23,18 @@ class InProcessKernelManager(KernelManager): kernel = Instance('IPython.kernel.inprocess.ipkernel.InProcessKernel') # the client class for KM.client() shortcut client_class = DottedObjectName('IPython.kernel.inprocess.BlockingInProcessKernelClient') - + + def _session_default(self): + # don't sign in-process messages + return Session(key=b'', parent=self) + #-------------------------------------------------------------------------- # Kernel management methods #-------------------------------------------------------------------------- def start_kernel(self, **kwds): from IPython.kernel.inprocess.ipkernel import InProcessKernel - self.kernel = InProcessKernel() + self.kernel = InProcessKernel(parent=self, session=self.session) def shutdown_kernel(self): self._kill_kernel() diff --git a/IPython/kernel/inprocess/tests/test_kernel.py b/IPython/kernel/inprocess/tests/test_kernel.py index 8cb51e4..3b9191d 100644 --- a/IPython/kernel/inprocess/tests/test_kernel.py +++ b/IPython/kernel/inprocess/tests/test_kernel.py @@ -25,7 +25,7 @@ class InProcessKernelTestCase(unittest.TestCase): def setUp(self): self.km = InProcessKernelManager() self.km.start_kernel() - self.kc = BlockingInProcessKernelClient(kernel=self.km.kernel) + self.kc = self.km.client() self.kc.start_channels() self.kc.wait_for_ready() @@ -61,7 +61,7 @@ class InProcessKernelTestCase(unittest.TestCase): kernel.shell.run_cell('print("foo")') self.assertEqual(io.stdout, 'foo\n') - kc = BlockingInProcessKernelClient(kernel=kernel) + kc = BlockingInProcessKernelClient(kernel=kernel, session=kernel.session) kernel.frontends.append(kc) kc.execute('print("bar")') out, err = assemble_output(kc.iopub_channel) diff --git a/IPython/kernel/inprocess/tests/test_kernelmanager.py b/IPython/kernel/inprocess/tests/test_kernelmanager.py index e191356..3ea1c86 100644 --- a/IPython/kernel/inprocess/tests/test_kernelmanager.py +++ b/IPython/kernel/inprocess/tests/test_kernelmanager.py @@ -24,7 +24,7 @@ class InProcessKernelManagerTestCase(unittest.TestCase): self.assert_(km.has_kernel) self.assert_(km.kernel is not None) - kc = BlockingInProcessKernelClient(kernel=km.kernel) + kc = km.client() self.assert_(not kc.channels_running) kc.start_channels() @@ -49,7 +49,7 @@ class InProcessKernelManagerTestCase(unittest.TestCase): """ km = InProcessKernelManager() km.start_kernel() - kc = BlockingInProcessKernelClient(kernel=km.kernel) + kc = km.client() kc.start_channels() kc.wait_for_ready() kc.execute('foo = 1') @@ -60,7 +60,7 @@ class InProcessKernelManagerTestCase(unittest.TestCase): """ km = InProcessKernelManager() km.start_kernel() - kc = BlockingInProcessKernelClient(kernel=km.kernel) + kc = km.client() kc.start_channels() kc.wait_for_ready() km.kernel.shell.push({'my_bar': 0, 'my_baz': 1}) @@ -75,7 +75,7 @@ class InProcessKernelManagerTestCase(unittest.TestCase): """ km = InProcessKernelManager() km.start_kernel() - kc = BlockingInProcessKernelClient(kernel=km.kernel) + kc = km.client() kc.start_channels() kc.wait_for_ready() km.kernel.shell.user_ns['foo'] = 1 @@ -92,7 +92,7 @@ class InProcessKernelManagerTestCase(unittest.TestCase): """ km = InProcessKernelManager() km.start_kernel() - kc = BlockingInProcessKernelClient(kernel=km.kernel) + kc = km.client() kc.start_channels() kc.wait_for_ready() kc.execute('%who') diff --git a/IPython/kernel/zmq/kernelapp.py b/IPython/kernel/zmq/kernelapp.py index 34c7c01..ba11549 100644 --- a/IPython/kernel/zmq/kernelapp.py +++ b/IPython/kernel/zmq/kernelapp.py @@ -36,7 +36,7 @@ from .heartbeat import Heartbeat from .ipkernel import IPythonKernel from .parentpoller import ParentPollerUnix, ParentPollerWindows from .session import ( - Session, session_flags, session_aliases, default_secure, + Session, session_flags, session_aliases, ) from .zmqshell import ZMQInteractiveShell @@ -342,7 +342,6 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp, @catch_config_error def initialize(self, argv=None): super(IPKernelApp, self).initialize(argv) - default_secure(self.config) self.init_blackhole() self.init_connection_file() self.init_poller() diff --git a/IPython/kernel/zmq/session.py b/IPython/kernel/zmq/session.py index 16582bb..c13ce0a 100644 --- a/IPython/kernel/zmq/session.py +++ b/IPython/kernel/zmq/session.py @@ -122,7 +122,7 @@ def default_secure(cfg): If Session.key/keyfile have not been set, set Session.key to a new random UUID. """ - + warnings.warn("default_secure is deprecated", DeprecationWarning) if 'Session' in cfg: if 'key' in cfg.Session or 'keyfile' in cfg.Session: return @@ -315,8 +315,11 @@ class Session(Configurable): # message signature related traits: - key = CBytes(b'', config=True, - help="""execution key, for extra authentication.""") + key = CBytes(config=True, + help="""execution key, for signing messages.""") + def _key_default(self): + return str_to_bytes(str(uuid.uuid4())) + def _key_changed(self): self._new_auth() @@ -433,6 +436,7 @@ class Session(Configurable): # ensure self._session_default() if necessary, so bsession is defined: self.session self.pid = os.getpid() + self._new_auth() @property def msg_id(self): diff --git a/IPython/kernel/zmq/tests/test_session.py b/IPython/kernel/zmq/tests/test_session.py index 7df16da..72e2350 100644 --- a/IPython/kernel/zmq/tests/test_session.py +++ b/IPython/kernel/zmq/tests/test_session.py @@ -1,16 +1,9 @@ -"""test building messages with streamsession""" +"""test building messages with Session""" -#------------------------------------------------------------------------------- -# Copyright (C) 2011 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Imports -#------------------------------------------------------------------------------- +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. +import hmac import os import uuid from datetime import datetime @@ -71,6 +64,10 @@ class TestSession(SessionTestCase): # ensure floats don't come out as Decimal: self.assertEqual(type(new_msg['content']['b']),type(new_msg['content']['b'])) + def test_default_secure(self): + self.assertIsInstance(self.session.key, bytes) + self.assertIsInstance(self.session.auth, hmac.HMAC) + def test_send(self): ctx = zmq.Context.instance() A = ctx.socket(zmq.PAIR) @@ -91,9 +88,10 @@ class TestSession(SessionTestCase): self.assertEqual(new_msg['parent_header'],msg['parent_header']) self.assertEqual(new_msg['metadata'],msg['metadata']) self.assertEqual(new_msg['buffers'],[b'bar']) - + content = msg['content'] header = msg['header'] + header['date'] = datetime.now() parent = msg['parent_header'] metadata = msg['metadata'] msg_type = header['msg_type'] @@ -109,7 +107,9 @@ class TestSession(SessionTestCase): self.assertEqual(new_msg['metadata'],msg['metadata']) self.assertEqual(new_msg['parent_header'],msg['parent_header']) self.assertEqual(new_msg['buffers'],[b'bar']) - + + header['date'] = datetime.now() + self.session.send(A, msg, ident=b'foo', buffers=[b'bar']) ident, new_msg = self.session.recv(B) self.assertEqual(ident[0], b'foo') diff --git a/IPython/parallel/apps/ipcontrollerapp.py b/IPython/parallel/apps/ipcontrollerapp.py index 4b16f58..4020595 100755 --- a/IPython/parallel/apps/ipcontrollerapp.py +++ b/IPython/parallel/apps/ipcontrollerapp.py @@ -48,7 +48,7 @@ from IPython.utils.localinterfaces import localhost, public_ips from IPython.utils.traitlets import Instance, Unicode, Bool, List, Dict, TraitError from IPython.kernel.zmq.session import ( - Session, session_aliases, session_flags, default_secure + Session, session_aliases, session_flags, ) from IPython.parallel.controller.heartmonitor import HeartMonitor @@ -314,8 +314,6 @@ class IPControllerApp(BaseParallelApplication): # no need to wite back the same file self.write_connection_files = False - # switch Session.key default to secure - default_secure(self.config) self.log.debug("Config changed") self.log.debug(repr(self.config))