##// END OF EJS Templates
configitems: register the 'factotum.executable' config
marmoute -
r33238:21b56882 default
parent child Browse files
Show More
@@ -1,134 +1,142 b''
1 1 # factotum.py - Plan 9 factotum integration for Mercurial
2 2 #
3 3 # Copyright (C) 2012 Steven Stallion <sstallion@gmail.com>
4 4 #
5 5 # This program is free software; you can redistribute it and/or modify it
6 6 # under the terms of the GNU General Public License as published by the
7 7 # Free Software Foundation; either version 2 of the License, or (at your
8 8 # option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful, but
11 11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 13 # Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License along
16 16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 18
19 19 '''http authentication with factotum
20 20
21 21 This extension allows the factotum(4) facility on Plan 9 from Bell Labs
22 22 platforms to provide authentication information for HTTP access. Configuration
23 23 entries specified in the auth section as well as authentication information
24 24 provided in the repository URL are fully supported. If no prefix is specified,
25 25 a value of "*" will be assumed.
26 26
27 27 By default, keys are specified as::
28 28
29 29 proto=pass service=hg prefix=<prefix> user=<username> !password=<password>
30 30
31 31 If the factotum extension is unable to read the required key, one will be
32 32 requested interactively.
33 33
34 34 A configuration section is available to customize runtime behavior. By
35 35 default, these entries are::
36 36
37 37 [factotum]
38 38 executable = /bin/auth/factotum
39 39 mountpoint = /mnt/factotum
40 40 service = hg
41 41
42 42 The executable entry defines the full path to the factotum binary. The
43 43 mountpoint entry defines the path to the factotum file service. Lastly, the
44 44 service entry controls the service name used when reading keys.
45 45
46 46 '''
47 47
48 48 from __future__ import absolute_import
49 49
50 50 import os
51 51 from mercurial.i18n import _
52 52 from mercurial import (
53 53 error,
54 54 httpconnection,
55 registrar,
55 56 url,
56 57 util,
57 58 )
58 59
59 60 urlreq = util.urlreq
60 61 passwordmgr = url.passwordmgr
61 62
62 63 ERRMAX = 128
63 64
64 65 _executable = _mountpoint = _service = None
65 66
67 configtable = {}
68 configitem = registrar.configitem(configtable)
69
70 configitem('factotum', 'executable',
71 default='/bin/auth/factotum',
72 )
73
66 74 def auth_getkey(self, params):
67 75 if not self.ui.interactive():
68 76 raise error.Abort(_('factotum not interactive'))
69 77 if 'user=' not in params:
70 78 params = '%s user?' % params
71 79 params = '%s !password?' % params
72 80 os.system("%s -g '%s'" % (_executable, params))
73 81
74 82 def auth_getuserpasswd(self, getkey, params):
75 83 params = 'proto=pass %s' % params
76 84 while True:
77 85 fd = os.open('%s/rpc' % _mountpoint, os.O_RDWR)
78 86 try:
79 87 os.write(fd, 'start %s' % params)
80 88 l = os.read(fd, ERRMAX).split()
81 89 if l[0] == 'ok':
82 90 os.write(fd, 'read')
83 91 status, user, passwd = os.read(fd, ERRMAX).split(None, 2)
84 92 if status == 'ok':
85 93 if passwd.startswith("'"):
86 94 if passwd.endswith("'"):
87 95 passwd = passwd[1:-1].replace("''", "'")
88 96 else:
89 97 raise error.Abort(_('malformed password string'))
90 98 return (user, passwd)
91 99 except (OSError, IOError):
92 100 raise error.Abort(_('factotum not responding'))
93 101 finally:
94 102 os.close(fd)
95 103 getkey(self, params)
96 104
97 105 def monkeypatch_method(cls):
98 106 def decorator(func):
99 107 setattr(cls, func.__name__, func)
100 108 return func
101 109 return decorator
102 110
103 111 @monkeypatch_method(passwordmgr)
104 112 def find_user_password(self, realm, authuri):
105 113 user, passwd = self.passwddb.find_user_password(realm, authuri)
106 114 if user and passwd:
107 115 self._writedebug(user, passwd)
108 116 return (user, passwd)
109 117
110 118 prefix = ''
111 119 res = httpconnection.readauthforuri(self.ui, authuri, user)
112 120 if res:
113 121 _, auth = res
114 122 prefix = auth.get('prefix')
115 123 user, passwd = auth.get('username'), auth.get('password')
116 124 if not user or not passwd:
117 125 if not prefix:
118 126 prefix = realm.split(' ')[0].lower()
119 127 params = 'service=%s prefix=%s' % (_service, prefix)
120 128 if user:
121 129 params = '%s user=%s' % (params, user)
122 130 user, passwd = auth_getuserpasswd(self, auth_getkey, params)
123 131
124 132 self.add_password(realm, authuri, user, passwd)
125 133 self._writedebug(user, passwd)
126 134 return (user, passwd)
127 135
128 136 def uisetup(ui):
129 137 global _executable
130 _executable = ui.config('factotum', 'executable', '/bin/auth/factotum')
138 _executable = ui.config('factotum', 'executable')
131 139 global _mountpoint
132 140 _mountpoint = ui.config('factotum', 'mountpoint', '/mnt/factotum')
133 141 global _service
134 142 _service = ui.config('factotum', 'service', 'hg')
General Comments 0
You need to be logged in to leave comments. Login now