-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathshadowauth.py
More file actions
74 lines (58 loc) · 1.84 KB
/
Copy pathshadowauth.py
File metadata and controls
74 lines (58 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python2
"""Authentication by parsing /etc/shadow.
curl -i http://root:bar@localhost:8090/
"""
import sys
sys.path.insert(0, '.')
import pwd
import re
from crypt import crypt
from httoop import UNAUTHORIZED
from circuits import BaseComponent, Debugger, handler
from circuits.http.events import authentication
from circuits.http.server.resource import method
from resource import BaseResource as Resource
from server import HTTPServer
class ShadowAuth(BaseComponent):
@handler('authentication')
def _on_shadow_auth(self, client):
auth = client.request.headers.element('Authorization')
if auth != 'Basic':
print 'Only basic auth supported...', auth
return
username, password = auth.params['username'], auth.params['password']
try:
passwd = pwd.getpwnam(username).pw_passwd
except KeyError:
print 'Unknown user'
return
if passwd == 'x':
print 'shadow password'
with open('/etc/shadow') as shadow:
rows = (line.strip().split(":") for line in shadow)
hash_ = [row[1] for row in rows if row[0] == user]
passwd = hash_ and _hash[0]
salt = re.match(r'\$.*\$.*\$', passwd).group()
if crypt(password, salt) == passwd:
print 'authentication was successful'
client.authenticated = True
return
print 'authentication failed'
raise UNAUTHORIZED()
@handler('routing', priority=2)
def _on_request(self, client):
client.authenticated = False
yield self.wait(self.fire(authentication(client)).event)
class Protected(Resource):
channel = '/'
@method
def GET(self, client):
return {"message": "Top secret!"}
GET.codec('application/json')
GET.conditions(lambda client: client.authenticated) # TODO: raise 401 Unauthorized
if __name__ == '__main__':
server = HTTPServer()
server.localhost += Protected()
server += ShadowAuth(channel=server.channel)
server += Debugger(events=True)
server.run()