~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/request.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-24 06:40:26 UTC
  • mfrom: (4160.2.16 bzrdir-open-gaol)
  • Revision ID: pqm@pqm.ubuntu.com-20090324064026-a5a7mmoiaev5mpc9
(andrew) Strengthen the smart server's jail,
        and add ignore_fallbacks parameter to BzrDir.open_branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
"""Basic server-side logic for dealing with requests.
18
 
 
19
 
**XXX**:
20
 
 
21
 
The class names are a little confusing: the protocol will instantiate a
22
 
SmartServerRequestHandler, whose dispatch_command method creates an instance of
23
 
a SmartServerRequest subclass.
24
 
 
25
 
The request_handlers registry tracks SmartServerRequest classes (rather than
26
 
SmartServerRequestHandler).
 
17
"""Infrastructure for server-side request handlers.
 
18
 
 
19
Interesting module attributes:
 
20
    * The request_handlers registry maps verb names to SmartServerRequest
 
21
      classes.
 
22
    * The jail_info threading.local() object is used to prevent accidental
 
23
      opening of BzrDirs outside of the backing transport, or any other
 
24
      transports placed in jail_info.transports.  The jail_info is reset on
 
25
      every call into a request handler (which can happen an arbitrary number
 
26
      of times during a request).
27
27
"""
28
28
 
 
29
# XXX: The class names are a little confusing: the protocol will instantiate a
 
30
# SmartServerRequestHandler, whose dispatch_command method creates an instance
 
31
# of a SmartServerRequest subclass.
 
32
 
 
33
 
29
34
import tempfile
 
35
import threading
30
36
 
31
37
from bzrlib import (
32
38
    bzrdir,
42
48
""")
43
49
 
44
50
 
 
51
jail_info = threading.local()
 
52
jail_info.transports = None
 
53
 
 
54
 
 
55
def _install_hook():
 
56
    bzrdir.BzrDir.hooks.install_named_hook(
 
57
        'pre_open', _pre_open_hook, 'checking server jail')
 
58
 
 
59
 
 
60
def _pre_open_hook(transport):
 
61
    allowed_transports = jail_info.transports
 
62
    if allowed_transports is None:
 
63
        return
 
64
    abspath = transport.base
 
65
    for allowed_transport in allowed_transports:
 
66
        try:
 
67
            allowed_transport.relpath(abspath)
 
68
        except errors.PathNotChild:
 
69
            continue
 
70
        else:
 
71
            return
 
72
    raise errors.BzrError('jail break: %r' % (abspath,))
 
73
 
 
74
 
 
75
_install_hook()
 
76
 
 
77
 
45
78
class SmartServerRequest(object):
46
79
    """Base class for request handlers.
47
80
 
121
154
        self._body_chunks = None
122
155
        return self.do_body(body_bytes)
123
156
 
 
157
    def setup_jail(self):
 
158
        jail_info.transports = [self._backing_transport]
 
159
 
 
160
    def teardown_jail(self):
 
161
        jail_info.transports = None
 
162
 
124
163
    def translate_client_path(self, client_path):
125
164
        """Translate a path received from a network client into a local
126
165
        relpath.
277
316
        # XXX: most of this error conversion is VFS-related, and thus ought to
278
317
        # be in SmartServerVFSRequestHandler somewhere.
279
318
        try:
280
 
            return callable(*args, **kwargs)
 
319
            self._command.setup_jail()
 
320
            try:
 
321
                return callable(*args, **kwargs)
 
322
            finally:
 
323
                self._command.teardown_jail()
281
324
        except (KeyboardInterrupt, SystemExit):
282
325
            raise
283
326
        except Exception, err: