1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import time
18 import string
19 import re
20
21 from spacewalk.common import rhnFlags
22 from spacewalk.common.rhnLog import log_debug, log_error
23 from spacewalk.common.rhnConfig import CFG
24 from spacewalk.common.rhnException import rhnFault
25 from spacewalk.common.rhnTranslate import _
26
27 from rhnLib import computeSignature
28
29
31 """ given a token:hostname, split it into a token-list, hostname """
32
33 token = string.split(token, ':')
34 hostname = ''
35 if len(token) > 5:
36 hostname = token[-1]
37 token = token[:-1]
38 else:
39
40 hostname = None
41 return token, hostname
42
43
45 """ verifies the validity of a proxy auth token
46
47 NOTE: X-RHN-Proxy-Auth described in proxy/broker/rhnProxyAuth.py
48 """
49
50 log_debug(4, auth_token)
51 token, hostname = splitProxyAuthToken(auth_token)
52 hostname = hostname.strip()
53 ipv4_regex = '^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$'
54
55
56
57
58 ipv6_regex = '^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?$'
59 hostname_is_ip_address = re.match(ipv4_regex, hostname) or re.match(ipv6_regex, hostname)
60
61 headers = rhnFlags.get('outputTransportOptions')
62 if len(token) < 5:
63
64 log_debug(4, "incomplete proxy authentication token: %s"
65 % auth_token)
66 headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (
67 1003, _("incomplete proxy authentication token: %s") % auth_token)
68 if not hostname_is_ip_address:
69 headers['X-RHN-Proxy-Auth-Origin'] = hostname
70 raise rhnFault(1003)
71
72 log_debug(5, "proxy auth token: %s, hostname: %s"
73 % (repr(token), hostname or 'n/a'))
74
75 proxyId, proxyUser, rhnServerTime, expireOffset, signature = token[:5]
76 computed = computeSignature(CFG.SECRET_KEY, proxyId, proxyUser,
77 rhnServerTime, expireOffset)
78
79 if computed != signature:
80 log_error("Proxy signature failed: proxy id='%s', proxy user='%s'" %
81 (proxyId, proxyUser))
82 log_debug(4, "Sent proxy signature %s does not match ours %s." % (
83 signature, computed))
84 headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (
85 1003, _("Sent proxy signature %s does not match ours %s.") % (
86 signature, computed))
87 if not hostname_is_ip_address:
88 headers['X-RHN-Proxy-Auth-Origin'] = hostname
89 raise rhnFault(1003)
90
91
92 rhnServerTime = float(rhnServerTime)
93 expireOffset = float(expireOffset)
94
95 if rhnServerTime + expireOffset < time.time():
96 log_debug(4, "Expired proxy authentication token")
97 headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (1004, "Expired")
98 if not hostname_is_ip_address:
99 headers['X-RHN-Proxy-Auth-Origin'] = hostname
100 raise rhnFault(1004)
101
102 log_debug(4, "Proxy auth OK: sigs match; not an expired token")
103 return 1
104
105
107 """ Authenticates a proxy carrying a clients request. For a valid or
108 unsigned request, this function returns 1 (OK), otherwise it raises
109 rhnFault
110
111 NOTE: X-RHN-Proxy-Auth described in proxy/broker/rhnProxyAuth.py
112 """
113
114 log_debug(3)
115 headers = rhnFlags.get('outputTransportOptions')
116 if not rhnFlags.test('X-RHN-Proxy-Auth'):
117
118 log_debug(4, "declined proxy authentication")
119 headers['X-RHN-Proxy-Auth-Error'] = '%s:%s' % (
120 1003, _("declined proxy authentication"))
121 raise rhnFault(1003)
122
123
124
125
126
127
128
129 tokens = string.split(rhnFlags.get('X-RHN-Proxy-Auth'), ',')
130 tokens = [token for token in tokens if token]
131
132 for auth_token in tokens:
133 _verifyProxyAuthToken(auth_token)
134
135
136 return 1
137
138
140 """ Authenticates a request from a client
141 For an unsigned request, this function returns 0 (request should be
142 coming from a client).
143 """
144
145 log_debug(3)
146 if not rhnFlags.test("AUTH_SESSION_TOKEN"):
147
148
149 log_debug(4, "declined client authentication for GET requests")
150 return 0
151
152 token = dict((k.lower(),v) for k,v in rhnFlags.get("AUTH_SESSION_TOKEN").items())
153
154 for k in ('x-rhn-server-id',
155 'x-rhn-auth-user-id',
156 'x-rhn-auth',
157 'x-rhn-auth-server-time',
158 'x-rhn-auth-expire-offset'):
159 if k not in token:
160
161 log_debug(4, "Declined auth of client for GET requests; "
162 "incomplete header info.")
163 return 0
164
165 clientId = token['x-rhn-server-id']
166 username = token['x-rhn-auth-user-id']
167 signature = token['x-rhn-auth']
168 rhnServerTime = token['x-rhn-auth-server-time']
169 expireOffset = token['x-rhn-auth-expire-offset']
170
171
172 computed = computeSignature(CFG.SECRET_KEY, clientId, username,
173 rhnServerTime, expireOffset)
174 if computed != signature:
175 log_debug(4, "Sent client signature %s does not match ours %s." % (
176 signature, computed))
177 raise rhnFault(33, "Invalid client session key")
178
179
180 rhnServerTime = float(rhnServerTime)
181 expireOffset = float(expireOffset)
182
183 if rhnServerTime + expireOffset < time.time():
184 log_debug(4, "Expired client authentication token")
185 raise rhnFault(34, "Expired client authentication token")
186
187 log_debug(4, "Client auth OK")
188 return 1
189