diff options
author | Tommi Virtanen <tv@eagain.net> | 2007-05-30 13:57:31 +0300 |
---|---|---|
committer | Tommi Virtanen <tv@eagain.net> | 2007-06-04 14:16:26 +0300 |
commit | bd1ee4fc013f169f1c052dc763c3e9ed602502c9 (patch) | |
tree | 04e054b5fe52efb1e801c4098d44bcc9359433d0 /gitosis/ssh.py | |
download | gitosis-dakkar-bd1ee4fc013f169f1c052dc763c3e9ed602502c9.tar.gz gitosis-dakkar-bd1ee4fc013f169f1c052dc763c3e9ed602502c9.tar.bz2 gitosis-dakkar-bd1ee4fc013f169f1c052dc763c3e9ed602502c9.zip |
Initial import.
Diffstat (limited to 'gitosis/ssh.py')
-rw-r--r-- | gitosis/ssh.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gitosis/ssh.py b/gitosis/ssh.py new file mode 100644 index 0000000..21f351a --- /dev/null +++ b/gitosis/ssh.py @@ -0,0 +1,104 @@ +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) + +def _getParser(): + import optparse + parser = optparse.OptionParser( + usage="%prog [--authkeys=FILE] KEYDIR") + parser.set_defaults( + authkeys=os.path.expanduser('~/.ssh/authorized_keys'), + ) + parser.add_option( + "--authkeys", + help="path to SSH authorized keys file") + return parser + +def main(): + parser = _getParser() + (options, args) = parser.parse_args() + + if len(args) != 1: + parser.error('Need one argument on the command line.') + + keydir, = args + + writeAuthorizedKeys( + path=options.authkeys, + keydir=keydir) |