Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mitogen
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
mitogen
Commits
a39cd44b
Commit
a39cd44b
authored
Feb 14, 2018
by
David Wilson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: add auth_id field.
parent
a54c96fa
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
30 deletions
+71
-30
docs/howitworks.rst
docs/howitworks.rst
+59
-18
mitogen/core.py
mitogen/core.py
+12
-12
No files found.
docs/howitworks.rst
View file @
a39cd44b
...
@@ -260,21 +260,55 @@ Stream Protocol
...
@@ -260,21 +260,55 @@ Stream Protocol
Once connected, a basic framing protocol is used to communicate between
Once connected, a basic framing protocol is used to communicate between
parent and child:
parent and child:
+--------------------+------+------------------------------------------------------+
.. list-table::
| Field | Size | Description |
:header-rows: 1
+====================+======+======================================================+
:widths: auto
| ``dst_id`` | 2 | Integer target context ID. |
+--------------------+------+------------------------------------------------------+
* - Field
| ``src_id`` | 2 | Integer source context ID. |
- Size
+--------------------+------+------------------------------------------------------+
- Description
| ``handle`` | 4 | Integer target handle in recipient. |
+--------------------+------+------------------------------------------------------+
* - `dst_id`
| ``reply_to`` | 4 | Integer response target ID. |
- 2
+--------------------+------+------------------------------------------------------+
- Integer target context ID. :py:class:`Router` delivers messages
| ``length`` | 4 | Message length |
locally when their `dst_id` matches :py:data:`mitogen.context_id`,
+--------------------+------+------------------------------------------------------+
otherwise they are routed up or downstream.
| ``data`` | n/a | Pickled message data. |
+--------------------+------+------------------------------------------------------+
* - `src_id`
- 2
- Integer source context ID. Used as the target of replies if any are
generated.
* - `auth_id`
- 2
- The context ID under whose authority the message is acting. See
:py:ref:`source-verification`.
* - `handle`
- 4
- Integer target handle in the destination context. This is one of the
:py:ref:`standard-handles`, or a dynamically generated handle used to
receive a one-time reply, such as the return value of a function call.
* - `reply_to`
- 4
- Integer target handle to direct any reply to this message. Used to
receive a one-time reply, such as the return value of a function call.
* - `length`
- 4
- Length of the data part of the message.
* - `data`
- n/a
- Message data, which may be raw or pickled.
.. _standard-handles:
Standard Handles
################
Masters listen on the following handles:
Masters listen on the following handles:
...
@@ -504,14 +538,21 @@ Source Verification
...
@@ -504,14 +538,21 @@ Source Verification
Before forwarding or dispatching a message it has received,
Before forwarding or dispatching a message it has received,
:py:class:`mitogen.core.Router` first looks up the corresponding
:py:class:`mitogen.core.Router` first looks up the corresponding
:py:class:`mitogen.core.Stream` it would use to send responses towards the
:py:class:`mitogen.core.Stream` it would use to send responses towards the
message source, and if the looked up stream does not match the stream on which
context ID listed in the `auth_id` field, and if the looked up stream does not
the message was received, the message is discarded and a warning is logged.
match the stream on which the message was received, the message is discarded
and a warning is logged.
This creates a trust chain leading up to the root of the tree, preventing
This creates a trust chain leading up to the root of the tree, preventing
downstream contexts from injecting messages appearing to be from the master or
downstream contexts from injecting messages appearing to be from the master or
any more trustworthy parent. In this way, privileged functionality such as
any more trustworthy parent. In this way, privileged functionality such as
:py:data:`CALL_FUNCTION <mitogen.core.CALL_FUNCTION>` can base trust decisions
:py:data:`CALL_FUNCTION <mitogen.core.CALL_FUNCTION>` can base trust decisions
on the accuracy of :py:ref:`src_id <stream-protocol>`.
on the accuracy of :py:ref:`auth_id <stream-protocol>`.
The `auth_id` field is separate from `src_id` in order to support granting
privilege to contexts that do not follow the tree'
s
natural
trust
chain
.
This
supports
cases
where
siblings
are
permitted
to
execute
code
on
one
another
,
or
where
isolated
processes
can
connect
to
a
listener
and
communicate
with
an
already
established
established
tree
.
Future
Future
...
...
mitogen/core.py
View file @
a39cd44b
...
@@ -217,6 +217,7 @@ def enable_profiling():
...
@@ -217,6 +217,7 @@ def enable_profiling():
class
Message
(
object
):
class
Message
(
object
):
dst_id
=
None
dst_id
=
None
src_id
=
None
src_id
=
None
auth_id
=
None
handle
=
None
handle
=
None
reply_to
=
None
reply_to
=
None
data
=
''
data
=
''
...
@@ -225,6 +226,7 @@ class Message(object):
...
@@ -225,6 +226,7 @@ class Message(object):
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
**
kwargs
):
self
.
src_id
=
mitogen
.
context_id
self
.
src_id
=
mitogen
.
context_id
self
.
auth_id
=
mitogen
.
context_id
vars
(
self
).
update
(
kwargs
)
vars
(
self
).
update
(
kwargs
)
def
_unpickle_context
(
self
,
context_id
,
name
):
def
_unpickle_context
(
self
,
context_id
,
name
):
...
@@ -264,9 +266,9 @@ class Message(object):
...
@@ -264,9 +266,9 @@ class Message(object):
raise
StreamError
(
'invalid message: %s'
,
ex
)
raise
StreamError
(
'invalid message: %s'
,
ex
)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'Message(%r, %r, %r, %r, %r..%d)'
%
(
return
'Message(%r, %r, %r, %r, %r
, %r
..%d)'
%
(
self
.
dst_id
,
self
.
src_id
,
self
.
handle
,
self
.
reply_to
,
self
.
dst_id
,
self
.
src_id
,
self
.
auth_id
,
self
.
handle
,
(
self
.
data
or
''
)[:
50
],
len
(
self
.
data
)
self
.
reply_to
,
(
self
.
data
or
''
)[:
50
],
len
(
self
.
data
)
)
)
...
@@ -307,8 +309,6 @@ def _queue_interruptible_get(queue, timeout=None, block=True):
...
@@ -307,8 +309,6 @@ def _queue_interruptible_get(queue, timeout=None, block=True):
if
timeout
is
not
None
:
if
timeout
is
not
None
:
timeout
+=
time
.
time
()
timeout
+=
time
.
time
()
LOG
.
info
(
'timeout = %r, block = %r'
,
timeout
,
block
)
msg
=
None
msg
=
None
while
msg
is
None
and
(
timeout
is
None
or
timeout
>
time
.
time
()):
while
msg
is
None
and
(
timeout
is
None
or
timeout
>
time
.
time
()):
try
:
try
:
...
@@ -407,6 +407,7 @@ class Importer(object):
...
@@ -407,6 +407,7 @@ class Importer(object):
'mitogen.compat.pkgutil'
,
'mitogen.compat.pkgutil'
,
'mitogen.fakessh'
,
'mitogen.fakessh'
,
'mitogen.master'
,
'mitogen.master'
,
'mitogen.parent'
,
'mitogen.ssh'
,
'mitogen.ssh'
,
'mitogen.sudo'
,
'mitogen.sudo'
,
'mitogen.utils'
,
'mitogen.utils'
,
...
@@ -635,6 +636,7 @@ class Stream(BasicStream):
...
@@ -635,6 +636,7 @@ class Stream(BasicStream):
protocol <stream-protocol>`.
protocol <stream-protocol>`.
"""
"""
_input_buf
=
''
_input_buf
=
''
auth_id
=
None
def
__init__
(
self
,
router
,
remote_id
,
**
kwargs
):
def
__init__
(
self
,
router
,
remote_id
,
**
kwargs
):
self
.
_router
=
router
self
.
_router
=
router
...
@@ -663,7 +665,7 @@ class Stream(BasicStream):
...
@@ -663,7 +665,7 @@ class Stream(BasicStream):
if
not
buf
:
if
not
buf
:
return
self
.
on_disconnect
(
broker
)
return
self
.
on_disconnect
(
broker
)
HEADER_FMT
=
'>hhLLL'
HEADER_FMT
=
'>hh
h
LLL'
HEADER_LEN
=
struct
.
calcsize
(
HEADER_FMT
)
HEADER_LEN
=
struct
.
calcsize
(
HEADER_FMT
)
def
_receive_one
(
self
,
broker
):
def
_receive_one
(
self
,
broker
):
...
@@ -674,7 +676,7 @@ class Stream(BasicStream):
...
@@ -674,7 +676,7 @@ class Stream(BasicStream):
# To support unpickling Contexts.
# To support unpickling Contexts.
msg
.
router
=
self
.
_router
msg
.
router
=
self
.
_router
(
msg
.
dst_id
,
msg
.
src_id
,
(
msg
.
dst_id
,
msg
.
src_id
,
msg
.
auth_id
,
msg
.
handle
,
msg
.
reply_to
,
msg_len
)
=
struct
.
unpack
(
msg
.
handle
,
msg
.
reply_to
,
msg_len
)
=
struct
.
unpack
(
self
.
HEADER_FMT
,
self
.
HEADER_FMT
,
self
.
_input_buf
[:
self
.
HEADER_LEN
]
self
.
_input_buf
[:
self
.
HEADER_LEN
]
...
@@ -711,7 +713,7 @@ class Stream(BasicStream):
...
@@ -711,7 +713,7 @@ class Stream(BasicStream):
def
_send
(
self
,
msg
):
def
_send
(
self
,
msg
):
IOLOG
.
debug
(
'%r._send(%r)'
,
self
,
msg
)
IOLOG
.
debug
(
'%r._send(%r)'
,
self
,
msg
)
pkt
=
struct
.
pack
(
'>hh
LLL'
,
msg
.
dst_id
,
msg
.
src
_id
,
pkt
=
struct
.
pack
(
'>hh
hLLL'
,
msg
.
dst_id
,
msg
.
src_id
,
msg
.
auth
_id
,
msg
.
handle
,
msg
.
reply_to
or
0
,
len
(
msg
.
data
)
msg
.
handle
,
msg
.
reply_to
or
0
,
len
(
msg
.
data
)
)
+
msg
.
data
)
+
msg
.
data
self
.
_output_buf
.
append
(
pkt
)
self
.
_output_buf
.
append
(
pkt
)
...
@@ -765,8 +767,6 @@ class Context(object):
...
@@ -765,8 +767,6 @@ class Context(object):
"""send `obj` to `handle`, and tell the broker we have output. May
"""send `obj` to `handle`, and tell the broker we have output. May
be called from any thread."""
be called from any thread."""
msg
.
dst_id
=
self
.
context_id
msg
.
dst_id
=
self
.
context_id
if
msg
.
src_id
is
None
:
msg
.
src_id
=
mitogen
.
context_id
self
.
router
.
route
(
msg
)
self
.
router
.
route
(
msg
)
def
send_async
(
self
,
msg
,
persist
=
False
):
def
send_async
(
self
,
msg
,
persist
=
False
):
...
@@ -979,10 +979,10 @@ class Router(object):
...
@@ -979,10 +979,10 @@ class Router(object):
IOLOG
.
debug
(
'%r._async_route(%r, %r)'
,
self
,
msg
,
stream
)
IOLOG
.
debug
(
'%r._async_route(%r, %r)'
,
self
,
msg
,
stream
)
# Perform source verification.
# Perform source verification.
if
stream
is
not
None
:
if
stream
is
not
None
:
expected_stream
=
self
.
_stream_by_id
.
get
(
msg
.
src
_id
,
expected_stream
=
self
.
_stream_by_id
.
get
(
msg
.
auth
_id
,
self
.
_stream_by_id
.
get
(
mitogen
.
parent_id
))
self
.
_stream_by_id
.
get
(
mitogen
.
parent_id
))
if
stream
!=
expected_stream
:
if
stream
!=
expected_stream
:
LOG
.
error
(
'%r: bad source: got %r from %r, should be from %r'
,
LOG
.
error
(
'%r: bad source: got
auth ID
%r from %r, should be from %r'
,
self
,
msg
,
stream
,
expected_stream
)
self
,
msg
,
stream
,
expected_stream
)
if
msg
.
dst_id
==
mitogen
.
context_id
:
if
msg
.
dst_id
==
mitogen
.
context_id
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment