Skip to content

Instantly share code, notes, and snippets.

@mentha
Created May 3, 2022 13:39
Show Gist options
  • Save mentha/dac51297dc4c47ff0ce8c2f08c91ae4c to your computer and use it in GitHub Desktop.
Save mentha/dac51297dc4c47ff0ce8c2f08c91ae4c to your computer and use it in GitHub Desktop.
manage pam_oath auth file
#!/usr/bin/env python3
# update OTP auth file of pam_oath
OATHFILE = '/etc/users.oath'
from base64 import b16encode, b16decode, b32encode
from sys import argv
import os
import subprocess as sp
if len(argv) < 2:
print(f'''usage: {argv[0]} [options] user
manage otp auth file
options:
-d remove oath auth
-l reset creds but do not show
-v view creds''')
exit(1)
cmd = None
user = None
for o in argv[1:]:
if not (cmd is None) and o in {'-d', '-l', '-v'}:
raise RuntimeError('conflicting operations')
if o == '-d':
cmd = 'delete'
elif o == '-l':
cmd = 'lock'
elif o == '-v':
cmd = 'view'
elif o.startswith('-'):
raise RuntimeError(f'unknown option {o}')
else:
if user:
raise RuntimeError('user already specified')
user = o
if not cmd:
cmd = 'update'
lines = None
with open(OATHFILE) as f:
lines = f.readlines()
uline = None
if cmd in {'update', 'delete', 'lock'}:
uidx = -1
for i in range(len(lines)):
l = lines[i].strip()
if l.startswith('#'):
continue
l = l.split()
if l[1] == user:
uline = l
uidx = i
break
if uidx >= 0:
lines.pop(uidx)
if cmd in {'update', 'lock'}:
k = None
with open('/dev/urandom', 'rb') as f:
k = f.read(10)
uline = ['HOTP/T30/6', user, '-', b16encode(k).decode().lower()]
lines.append(' '.join(uline))
with open(OATHFILE, 'w') as f:
for l in lines:
f.write(l.strip() + '\n')
if cmd in {'update', 'view'}:
if not uline:
raise RuntimeError('user not found')
b32 = b32encode(b16decode(uline[3].upper())).decode()
print(f'secret in base32 is {b32}')
sp.run(['qrencode', '-t', 'ANSI256UTF8'], input=f'otpauth://totp/pam_oath:{user}@{os.uname().nodename}?secret={b32}&issuer=pam_oath', universal_newlines=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment