~launchpad-pqm/launchpad/devel

10918.2.3 by Steve Kowalik
Merge in the code for poppy-sftp
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
# This is a Twisted application config file.  To run, use:
5
#     twistd -noy sftp.tac
6
# or similar.  Refer to the twistd(1) man page for details.
7
8
import os
9
10
from twisted.application import service
11057.4.3 by Jonathan Lange
Use the DoNothing adapter.
11
from twisted.conch.interfaces import ISession
10918.2.3 by Steve Kowalik
Merge in the code for poppy-sftp
12
from twisted.conch.ssh import filetransfer
13
from twisted.cred.portal import IRealm, Portal
14
from twisted.python import components
15
from twisted.web.xmlrpc import Proxy
16
17
from zope.interface import implements
18
19
from canonical.config import config
20
from canonical.launchpad.daemons import tachandler
21
22
from lp.poppy.twistedsftp import SFTPServer
23
from lp.services.sshserver.auth import (
24
    LaunchpadAvatar, PublicKeyFromLaunchpadChecker)
25
from lp.services.sshserver.service import SSHService
11057.4.3 by Jonathan Lange
Use the DoNothing adapter.
26
from lp.services.sshserver.session import DoNothingSession
10918.2.3 by Steve Kowalik
Merge in the code for poppy-sftp
27
28
# XXX: Rename this file to something that doesn't mention poppy. Talk to
29
# bigjools.
30
31
32
def make_portal():
33
    """Create and return a `Portal` for the SSH service.
34
35
    This portal accepts SSH credentials and returns our customized SSH
36
    avatars (see `LaunchpadAvatar`).
37
    """
38
    authentication_proxy = Proxy(
39
        config.poppy.authentication_endpoint)
40
    portal = Portal(Realm(authentication_proxy))
41
    portal.registerChecker(
42
        PublicKeyFromLaunchpadChecker(authentication_proxy))
43
    return portal
44
45
46
class Realm:
47
    implements(IRealm)
48
49
    def __init__(self, authentication_proxy):
50
        self.authentication_proxy = authentication_proxy
51
52
    def requestAvatar(self, avatar_id, mind, *interfaces):
53
        # Fetch the user's details from the authserver
54
        deferred = mind.lookupUserDetails(
55
            self.authentication_proxy, avatar_id)
56
57
        # Once all those details are retrieved, we can construct the avatar.
58
        def got_user_dict(user_dict):
59
            avatar = LaunchpadAvatar(user_dict)
60
            return interfaces[0], avatar, avatar.logout
61
62
        return deferred.addCallback(got_user_dict)
63
64
65
def get_poppy_root():
66
    """Return the poppy root to use for this server.
67
68
    If the POPPY_ROOT environment variable is set, use that. If not, use
69
    config.poppy.fsroot.
70
    """
71
    poppy_root = os.environ.get('POPPY_ROOT', None)
72
    if poppy_root:
73
        return poppy_root
74
    return config.poppy.fsroot
75
76
77
def poppy_sftp_adapter(avatar):
78
    return SFTPServer(avatar, get_poppy_root())
79
80
81
components.registerAdapter(
82
    poppy_sftp_adapter, LaunchpadAvatar, filetransfer.ISFTPServer)
83
11057.4.3 by Jonathan Lange
Use the DoNothing adapter.
84
components.registerAdapter(DoNothingSession, LaunchpadAvatar, ISession)
85
10918.2.3 by Steve Kowalik
Merge in the code for poppy-sftp
86
87
# Construct an Application that has the Poppy SSH server.
88
application = service.Application('poppy-sftp')
89
svc = SSHService(
90
    portal=make_portal(),
91
    private_key_path=config.poppy.host_key_private,
92
    public_key_path=config.poppy.host_key_public,
93
    oops_configuration='poppy',
94
    main_log='poppy',
95
    access_log='poppy.access',
96
    access_log_path=config.poppy.access_log,
97
    strport=config.poppy.port,
98
    idle_timeout=config.poppy.idle_timeout,
99
    banner=config.poppy.banner)
100
svc.setServiceParent(application)
101
102
# Service that announces when the daemon is ready
103
tachandler.ReadyService().setServiceParent(application)