annotate hgext/factotum.py @ 16383:f5dd179bfa4a

plan9: initial support for plan 9 from bell labs This patch contains support for Plan 9 from Bell Labs. A README is provided in contrib/plan9 which describes the port in greater detail. A new extension is also provided named factotum which permits the factotum(4) authentication agent to provide credentials for HTTP repositories. This extension is also applicable to other POSIX platforms which make use of Plan 9 from User Space (aka plan9ports).
author Steven Stallion <sstallion@gmail.com>
date Sun, 08 Apr 2012 12:43:41 -0700
parents
children cef755f86d5c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
1 # factotum.py - Plan 9 factotum integration for Mercurial
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
2 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
3 # Copyright (C) 2012 Steven Stallion <sstallion@gmail.com>
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
4 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
5 # This program is free software; you can redistribute it and/or modify it
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
6 # under the terms of the GNU General Public License as published by the
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
7 # Free Software Foundation; either version 2 of the License, or (at your
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
8 # option) any later version.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
9 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
10 # This program is distributed in the hope that it will be useful, but
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
13 # Public License for more details.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
14 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
15 # You should have received a copy of the GNU General Public License along
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
16 # with this program; if not, write to the Free Software Foundation, Inc.,
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
18
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
19 '''http authentication with factotum
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
20
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
21 This extension allows the factotum facility on Plan 9 from Bell Labs platforms
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
22 to provide authentication information for HTTP access. Configuration entries
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
23 specified in the auth section as well as authentication information provided
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
24 in the repository URL are fully supported. If no prefix is specified, a value
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
25 of ``*`` will be assumed.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
26
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
27 By default, keys are specified as::
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
28
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
29 proto=pass service=hg prefix=<prefix> user=<username> !password=<password>
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
30
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
31 If the factotum extension is unable to read the required key, one will be
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
32 requested interactively.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
33
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
34 A configuration section is available to customize runtime behavior. By
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
35 default, these entries are::
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
36
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
37 [factotum]
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
38 mount = /mnt/factotum
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
39 path = /bin/auth/factotum
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
40 service = hg
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
41
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
42 The mount entry defines the mount point for the factotum file service. The
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
43 path entry defines the full path to the factotum binary. Lastly, the service
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
44 entry controls the service name used when reading keys.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
45
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
46 '''
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
47
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
48 from mercurial.i18n import _
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
49 from mercurial.url import passwordmgr
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
50 from mercurial import httpconnection, urllib2, util
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
51 import os
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
52
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
53 ERRMAX = 128
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
54
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
55 def auth_getkey(self, params):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
56 if not self.ui.interactive():
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
57 raise util.Abort(_('factotum not interactive'))
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
58 if 'user=' not in params:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
59 params = '%s user?' % params
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
60 params = '%s !password?' % params
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
61 os.system("%s -g '%s'" % (_path, params))
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
62
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
63 def auth_getuserpasswd(self, getkey, params):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
64 params = 'proto=pass %s' % params
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
65 while True:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
66 fd = os.open('%s/rpc' % _mount, os.O_RDWR)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
67 try:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
68 try:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
69 os.write(fd, 'start %s' % params)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
70 l = os.read(fd, ERRMAX).split()
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
71 if l[0] == 'ok':
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
72 os.write(fd, 'read')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
73 l = os.read(fd, ERRMAX).split()
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
74 if l[0] == 'ok':
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
75 return l[1:]
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
76 except (OSError, IOError):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
77 raise util.Abort(_('factotum not responding'))
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
78 finally:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
79 os.close(fd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
80 getkey(self, params)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
81
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
82 def monkeypatch_method(cls):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
83 def decorator(func):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
84 setattr(cls, func.__name__, func)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
85 return func
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
86 return decorator
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
87
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
88 @monkeypatch_method(passwordmgr)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
89 def find_user_password(self, realm, authuri):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
90 user, passwd = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
91 self, realm, authuri)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
92 if user and passwd:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
93 self._writedebug(user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
94 return (user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
95
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
96 prefix = ''
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
97 res = httpconnection.readauthforuri(self.ui, authuri, user)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
98 if res:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
99 _, auth = res
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
100 prefix = auth.get('prefix')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
101 user, passwd = auth.get('username'), auth.get('password')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
102 if not user or not passwd:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
103 if not prefix:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
104 prefix = '*'
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
105 params = 'service=%s prefix=%s' % (_service, prefix)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
106 if user:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
107 params = '%s user=%s' % (params, user)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
108 user, passwd = auth_getuserpasswd(self, auth_getkey, params)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
109
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
110 self.add_password(realm, authuri, user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
111 self._writedebug(user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
112 return (user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
113
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
114 def uisetup(ui):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
115 global _mount
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
116 _mount = ui.config('factotum', 'mount', '/mnt/factotum')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
117 global _path
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
118 _path = ui.config('factotum', 'path', '/bin/auth/factotum')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
119 global _service
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
120 _service = ui.config('factotum', 'service', 'hg')