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) |