-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth_eos.py
executable file
·136 lines (110 loc) · 3.79 KB
/
auth_eos.py
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python
"""
A Python Script that authenticates against Kerberos using credentials from a keyring
"""
from __future__ import print_function
import keyring
import getpass
import getopt
import sys
import pexpect
import subprocess
import logging
import time
import urllib2
LOG_FORMAT = "%(levelname)s: %(message)s"
REALM = "EOS.NCSU.EDU"
CELLS = ["eos.ncsu.edu", "unity.ncsu.edu"]
ARGS = "sgv"
USAGE = "Usage: auth_eos -s \t set credentials \n\
auth_eos -g \t authenticate"
def set_credentials():
user = raw_input("Enter username:")
passwd = getpass.getpass("Enter password for {}@{}:".format(user, REALM))
logging.info("Saving username")
keyring.set_password(REALM, "username", user)
logging.info("Saving password")
keyring.set_password(REALM, "password", passwd)
def get_credentials():
logging.info("Getting username")
user = keyring.get_password(REALM, "username")
logging.info("Getting password")
passwd = keyring.get_password(REALM, "password")
return user, passwd
def kinit(user_fq, passwd):
initialize = pexpect.spawn('kinit', [user_fq])
idx = initialize.expect(['Password for {}:'.format(user_fq), pexpect.EOF, pexpect.TIMEOUT])
if idx == 0:
logging.info("Received password prompt. Sending password.")
initialize.sendline(passwd)
else:
logging.error("Did not receive password prompt.")
sys.exit(-1)
idx = initialize.expect(['kinit: Password incorrect while getting initial credentials', pexpect.EOF, pexpect.TIMEOUT])
if idx == 0:
logging.error("Wrong password to kinit")
sys.exit(-1)
elif idx == 1:
logging.info("kinit: Success")
else:
logging.error("kinit: No response")
def aklog(cells):
for cell in cells:
logging.info("Getting token for {}".format(cell))
subprocess.call(["aklog", "-c", cell, "-k", REALM])
def is_connected_by_poll_google():
try:
urllib2.urlopen("http://www.google.com").close()
except urllib2.URLError:
return False
else:
return True
def wait_for_connection(is_connected=is_connected_by_poll_google, timeout=30, interval=2):
end_time = time.time() + timeout
while time.time() < end_time:
if is_connected():
logging.info("Connection available")
return True
logging.warn("Connection unavailable, retrying.")
time.sleep(interval)
return False
def authenticate(user, passwd, cells=CELLS):
logging.info("Checking for connectivity.")
if not wait_for_connection():
logging.error("No connection available.")
sys.exit(1)
user_fq = "{}@{}".format(user, REALM)
logging.info("Getting ticket-granting ticket through kinit.")
kinit(user_fq, passwd)
logging.info("Getting tokens through aklog")
aklog(cells)
if __name__ == "__main__":
try:
opts, args = getopt.getopt(sys.argv[1:], ARGS)
except getopt.GetoptError as e:
print(e)
print(USAGE)
sys.exit(2)
pure_opts = [o for o,a in opts]
if '-v' in pure_opts:
logging.basicConfig(format=LOG_FORMAT, level=logging.DEBUG)
logging.info("Enabling verbose output.")
else:
logging.basicConfig(format=LOG_FORMAT)
if '-s' in pure_opts and '-g' in pure_opts:
logging.error("Both -s and -g. Cannot set and authenticate simultaneously.")
print(USAGE)
sys.exit(3)
elif '-s' in pure_opts:
logging.info("Setting credentials to keyring")
set_credentials()
elif '-g' in pure_opts:
logging.info("Getting credentials from keyring")
creds = get_credentials()
logging.info("Authenticating")
authenticate(creds[0], creds[1])
else:
logging.error("Neither -s and -g.")
print(USAGE)
sys.exit(3)
sys.exit(0)