Show More
@@ -265,6 +265,8 b' class IPythonConsoleApp(Configurable):' | |||||
265 | setattr(self, name, cfg[name]) |
|
265 | setattr(self, name, cfg[name]) | |
266 | if 'key' in cfg: |
|
266 | if 'key' in cfg: | |
267 | self.config.Session.key = str_to_bytes(cfg['key']) |
|
267 | self.config.Session.key = str_to_bytes(cfg['key']) | |
|
268 | if 'signature_scheme' in cfg: | |||
|
269 | self.config.Session.signature_scheme = cfg['signature_scheme'] | |||
268 |
|
270 | |||
269 | def init_ssh(self): |
|
271 | def init_ssh(self): | |
270 | """set up ssh tunnels, if needed.""" |
|
272 | """set up ssh tunnels, if needed.""" |
@@ -50,7 +50,9 b' from IPython.utils.traitlets import (' | |||||
50 | #----------------------------------------------------------------------------- |
|
50 | #----------------------------------------------------------------------------- | |
51 |
|
51 | |||
52 | def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0, |
|
52 | def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, hb_port=0, | |
53 |
control_port=0, ip=LOCALHOST, key=b'', transport='tcp' |
|
53 | control_port=0, ip=LOCALHOST, key=b'', transport='tcp', | |
|
54 | signature_scheme='hmac-sha256', | |||
|
55 | ): | |||
54 | """Generates a JSON config file, including the selection of random ports. |
|
56 | """Generates a JSON config file, including the selection of random ports. | |
55 |
|
57 | |||
56 | Parameters |
|
58 | Parameters | |
@@ -78,7 +80,15 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, ' | |||||
78 | The ip address the kernel will bind to. |
|
80 | The ip address the kernel will bind to. | |
79 |
|
81 | |||
80 | key : str, optional |
|
82 | key : str, optional | |
81 |
The Session key used for |
|
83 | The Session key used for message authentication. | |
|
84 | ||||
|
85 | signature_scheme : str, optional | |||
|
86 | The scheme used for message authentication. | |||
|
87 | This has the form 'digest-hash', where 'digest' | |||
|
88 | is the scheme used for digests, and 'hash' is the name of the hash function | |||
|
89 | used by the digest scheme. | |||
|
90 | Currently, 'hmac' is the only supported digest scheme, | |||
|
91 | and 'sha256' is the default hash function. | |||
82 |
|
92 | |||
83 | """ |
|
93 | """ | |
84 | # default to temporary connector file |
|
94 | # default to temporary connector file | |
@@ -129,6 +139,7 b' def write_connection_file(fname=None, shell_port=0, iopub_port=0, stdin_port=0, ' | |||||
129 | cfg['ip'] = ip |
|
139 | cfg['ip'] = ip | |
130 | cfg['key'] = bytes_to_str(key) |
|
140 | cfg['key'] = bytes_to_str(key) | |
131 | cfg['transport'] = transport |
|
141 | cfg['transport'] = transport | |
|
142 | cfg['signature_scheme'] = signature_scheme | |||
132 |
|
143 | |||
133 | with open(fname, 'w') as f: |
|
144 | with open(fname, 'w') as f: | |
134 | f.write(json.dumps(cfg, indent=2)) |
|
145 | f.write(json.dumps(cfg, indent=2)) | |
@@ -380,6 +391,7 b' class ConnectionFileMixin(HasTraits):' | |||||
380 | _connection_file_written = Bool(False) |
|
391 | _connection_file_written = Bool(False) | |
381 |
|
392 | |||
382 | transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True) |
|
393 | transport = CaselessStrEnum(['tcp', 'ipc'], default_value='tcp', config=True) | |
|
394 | signature_scheme = Unicode('') | |||
383 |
|
395 | |||
384 | ip = Unicode(LOCALHOST, config=True, |
|
396 | ip = Unicode(LOCALHOST, config=True, | |
385 | help="""Set the kernel\'s IP address [default localhost]. |
|
397 | help="""Set the kernel\'s IP address [default localhost]. | |
@@ -427,6 +439,7 b' class ConnectionFileMixin(HasTraits):' | |||||
427 | stdin_port=self.stdin_port, |
|
439 | stdin_port=self.stdin_port, | |
428 | hb_port=self.hb_port, |
|
440 | hb_port=self.hb_port, | |
429 | control_port=self.control_port, |
|
441 | control_port=self.control_port, | |
|
442 | signature_scheme=self.signature_scheme, | |||
430 | ) |
|
443 | ) | |
431 |
|
444 | |||
432 | def cleanup_connection_file(self): |
|
445 | def cleanup_connection_file(self): | |
@@ -463,6 +476,7 b' class ConnectionFileMixin(HasTraits):' | |||||
463 | stdin_port=self.stdin_port, iopub_port=self.iopub_port, |
|
476 | stdin_port=self.stdin_port, iopub_port=self.iopub_port, | |
464 | shell_port=self.shell_port, hb_port=self.hb_port, |
|
477 | shell_port=self.shell_port, hb_port=self.hb_port, | |
465 | control_port=self.control_port, |
|
478 | control_port=self.control_port, | |
|
479 | signature_scheme=self.signature_scheme, | |||
466 | ) |
|
480 | ) | |
467 | # write_connection_file also sets default ports: |
|
481 | # write_connection_file also sets default ports: | |
468 | for name in port_names: |
|
482 | for name in port_names: | |
@@ -479,7 +493,10 b' class ConnectionFileMixin(HasTraits):' | |||||
479 | self.ip = cfg['ip'] |
|
493 | self.ip = cfg['ip'] | |
480 | for name in port_names: |
|
494 | for name in port_names: | |
481 | setattr(self, name, cfg[name]) |
|
495 | setattr(self, name, cfg[name]) | |
482 | self.session.key = str_to_bytes(cfg['key']) |
|
496 | if 'key' in cfg: | |
|
497 | self.session.key = str_to_bytes(cfg['key']) | |||
|
498 | if cfg.get('signature_scheme'): | |||
|
499 | self.session.signature_scheme = cfg['signature_scheme'] | |||
483 |
|
500 | |||
484 | #-------------------------------------------------------------------------- |
|
501 | #-------------------------------------------------------------------------- | |
485 | # Creating connected sockets |
|
502 | # Creating connected sockets |
@@ -24,6 +24,7 b' Authors:' | |||||
24 | # Imports |
|
24 | # Imports | |
25 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
26 |
|
26 | |||
|
27 | import hashlib | |||
27 | import hmac |
|
28 | import hmac | |
28 | import logging |
|
29 | import logging | |
29 | import os |
|
30 | import os | |
@@ -50,7 +51,9 b' from IPython.utils.importstring import import_item' | |||||
50 | from IPython.utils.jsonutil import extract_dates, squash_dates, date_default |
|
51 | from IPython.utils.jsonutil import extract_dates, squash_dates, date_default | |
51 | from IPython.utils.py3compat import str_to_bytes, str_to_unicode |
|
52 | from IPython.utils.py3compat import str_to_bytes, str_to_unicode | |
52 | from IPython.utils.traitlets import (CBytes, Unicode, Bool, Any, Instance, Set, |
|
53 | from IPython.utils.traitlets import (CBytes, Unicode, Bool, Any, Instance, Set, | |
53 |
DottedObjectName, CUnicode, Dict, Integer |
|
54 | DottedObjectName, CUnicode, Dict, Integer, | |
|
55 | TraitError, | |||
|
56 | ) | |||
54 | from IPython.kernel.zmq.serialize import MAX_ITEMS, MAX_BYTES |
|
57 | from IPython.kernel.zmq.serialize import MAX_ITEMS, MAX_BYTES | |
55 |
|
58 | |||
56 | #----------------------------------------------------------------------------- |
|
59 | #----------------------------------------------------------------------------- | |
@@ -308,10 +311,26 b' class Session(Configurable):' | |||||
308 | help="""execution key, for extra authentication.""") |
|
311 | help="""execution key, for extra authentication.""") | |
309 | def _key_changed(self, name, old, new): |
|
312 | def _key_changed(self, name, old, new): | |
310 | if new: |
|
313 | if new: | |
311 | self.auth = hmac.HMAC(new) |
|
314 | self.auth = hmac.HMAC(new, digestmod=self.digest_mod) | |
312 | else: |
|
315 | else: | |
313 | self.auth = None |
|
316 | self.auth = None | |
314 |
|
317 | |||
|
318 | signature_scheme = Unicode('hmac-sha256', config=True, | |||
|
319 | help="""The digest scheme used to construct the message signatures. | |||
|
320 | Must have the form 'hmac-HASH'.""") | |||
|
321 | def _signature_scheme_changed(self, name, old, new): | |||
|
322 | if not new.startswith('hmac-'): | |||
|
323 | raise TraitError("signature_scheme must start with 'hmac-', got %r" % new) | |||
|
324 | hash_name = new.split('-', 1)[1] | |||
|
325 | try: | |||
|
326 | self.digest_mod = getattr(hashlib, hash_name) | |||
|
327 | except AttributeError: | |||
|
328 | raise TraitError("hashlib has no such attribute: %s" % hash_name) | |||
|
329 | ||||
|
330 | digest_mod = Any() | |||
|
331 | def _digest_mod_default(self): | |||
|
332 | return hashlib.sha256 | |||
|
333 | ||||
315 | auth = Instance(hmac.HMAC) |
|
334 | auth = Instance(hmac.HMAC) | |
316 |
|
335 | |||
317 | digest_history = Set() |
|
336 | digest_history = Set() | |
@@ -387,6 +406,11 b' class Session(Configurable):' | |||||
387 | key : bytes |
|
406 | key : bytes | |
388 | The key used to initialize an HMAC signature. If unset, messages |
|
407 | The key used to initialize an HMAC signature. If unset, messages | |
389 | will not be signed or checked. |
|
408 | will not be signed or checked. | |
|
409 | signature_scheme : str | |||
|
410 | The message digest scheme. Currently must be of the form 'hmac-HASH', | |||
|
411 | where 'HASH' is a hashing function available in Python's hashlib. | |||
|
412 | The default is 'hmac-sha256'. | |||
|
413 | This is ignored if 'key' is empty. | |||
390 | keyfile : filepath |
|
414 | keyfile : filepath | |
391 | The file containing a key. If this is set, `key` will be |
|
415 | The file containing a key. If this is set, `key` will be | |
392 | initialized to the contents of the file. |
|
416 | initialized to the contents of the file. |
General Comments 0
You need to be logged in to leave comments.
Login now