gitosis/gitosis/ssh.py
Tommi Virtanen 8a0654abe2 Refactor command line utilities to share setup.
Hide internal gitosis-ssh and gitosis-gitweb, it's all in gitosis-run-hook.
2007-09-03 17:09:12 -07:00

80 lines
2 KiB
Python

import os, errno, re
def readKeys(keydir):
"""
Read SSH public keys from ``keydir/*.pub``
"""
for filename in os.listdir(keydir):
if filename.startswith('.'):
continue
basename, ext = os.path.splitext(filename)
if ext != '.pub':
continue
path = os.path.join(keydir, filename)
f = file(path)
try:
line = f.readline()
finally:
f.close()
line = line.rstrip('\n')
yield (basename, line)
COMMENT = '### autogenerated by gitosis, DO NOT EDIT'
def generateAuthorizedKeys(keys):
TEMPLATE=('command="gitosis-serve %(user)s",no-port-forwarding,'
+'no-X11-forwarding,no-agent-forwarding,no-pty %(key)s')
yield COMMENT
for (user, key) in keys:
yield TEMPLATE % dict(user=user, key=key)
_COMMAND_RE = re.compile('^command="(/[^ "]+/)?gitosis-serve [^"]+",no-port-forw'
+'arding,no-X11-forwarding,no-agent-forwardi'
+'ng,no-pty .*')
def filterAuthorizedKeys(fp):
"""
Read lines from ``fp``, filter out autogenerated ones.
Note removes newlines.
"""
for line in fp:
line = line.rstrip('\n')
if line == COMMENT:
continue
if _COMMAND_RE.match(line):
continue
yield line
def writeAuthorizedKeys(path, keydir):
tmp = '%s.%d.tmp' % (path, os.getpid())
try:
in_ = file(path)
except IOError, e:
if e.errno == errno.ENOENT:
in_ = None
else:
raise
try:
out = file(tmp, 'w')
try:
if in_ is not None:
for line in filterAuthorizedKeys(in_):
print >>out, line
keygen = readKeys(keydir)
for line in generateAuthorizedKeys(keygen):
print >>out, line
os.fsync(out)
finally:
out.close()
finally:
if in_ is not None:
in_.close()
os.rename(tmp, path)