added ssh-principals
This commit is contained in:
parent
f7c1a0e219
commit
a6c329e7be
|
@ -10,6 +10,7 @@ import shutil
|
||||||
|
|
||||||
from gitosis import repository
|
from gitosis import repository
|
||||||
from gitosis import ssh
|
from gitosis import ssh
|
||||||
|
from gitosis import ssh_principals
|
||||||
from gitosis import gitweb
|
from gitosis import gitweb
|
||||||
from gitosis import gitdaemon
|
from gitosis import gitdaemon
|
||||||
from gitosis import app
|
from gitosis import app
|
||||||
|
@ -47,6 +48,11 @@ def post_update(cfg, git_dir):
|
||||||
path=authorized_keys,
|
path=authorized_keys,
|
||||||
keydir=os.path.join(export, 'keydir'),
|
keydir=os.path.join(export, 'keydir'),
|
||||||
)
|
)
|
||||||
|
principals = util.getSSHPrincipalsPath(config=cfg)
|
||||||
|
ssh.writePrincipals(
|
||||||
|
path=principals,
|
||||||
|
principals=os.path.join(export, 'principals'),
|
||||||
|
)
|
||||||
|
|
||||||
class Main(app.App):
|
class Main(app.App):
|
||||||
def create_parser(self):
|
def create_parser(self):
|
||||||
|
|
81
gitosis/ssh_principals.py
Normal file
81
gitosis/ssh_principals.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import os, errno, re
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger('gitosis.ssh')
|
||||||
|
|
||||||
|
_ACCEPTABLE_USER_RE = re.compile(r'^[a-zA-Z][a-zA-Z0-9_.-]*(@[a-zA-Z][a-zA-Z0-9.-]*)?$')
|
||||||
|
|
||||||
|
def isSafeUsername(user):
|
||||||
|
match = _ACCEPTABLE_USER_RE.match(user)
|
||||||
|
return (match is not None)
|
||||||
|
|
||||||
|
def readPrincipals(principals):
|
||||||
|
"""
|
||||||
|
Read SSH principals from ``principals``
|
||||||
|
"""
|
||||||
|
f = file(principals)
|
||||||
|
for line in f:
|
||||||
|
if not isSafeUsername(line):
|
||||||
|
log.warn('Unsafe SSH username in principalfile: %r', line)
|
||||||
|
continue
|
||||||
|
line = line.rstrip('\n')
|
||||||
|
yield (line)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
COMMENT = '### autogenerated by gitosis, DO NOT EDIT'
|
||||||
|
|
||||||
|
def generatePrincipals(keys):
|
||||||
|
TEMPLATE=('command="gitosis-serve %(user)s",no-port-forwarding,'
|
||||||
|
+'no-X11-forwarding,no-agent-forwarding,no-pty %(user)s')
|
||||||
|
|
||||||
|
yield COMMENT
|
||||||
|
for (user) in keys:
|
||||||
|
yield TEMPLATE % dict(user=user)
|
||||||
|
|
||||||
|
_COMMAND_RE = re.compile('^command="(/[^ "]+/)?gitosis-serve [^"]+",no-port-forw'
|
||||||
|
+'arding,no-X11-forwarding,no-agent-forwardi'
|
||||||
|
+'ng,no-pty .*')
|
||||||
|
|
||||||
|
def filterPrincipals(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 writePrincipals(path, principals):
|
||||||
|
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 filterPrincipals(in_):
|
||||||
|
print >>out, line
|
||||||
|
|
||||||
|
keygen = readPrincipals(principals)
|
||||||
|
for line in generatePrincipals(keygen):
|
||||||
|
print >>out, line
|
||||||
|
|
||||||
|
os.fsync(out)
|
||||||
|
finally:
|
||||||
|
out.close()
|
||||||
|
finally:
|
||||||
|
if in_ is not None:
|
||||||
|
in_.close()
|
||||||
|
os.rename(tmp, path)
|
|
@ -34,3 +34,10 @@ def getSSHAuthorizedKeysPath(config):
|
||||||
except (NoSectionError, NoOptionError):
|
except (NoSectionError, NoOptionError):
|
||||||
path = os.path.expanduser('~/.ssh/authorized_keys')
|
path = os.path.expanduser('~/.ssh/authorized_keys')
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
def getSSHPrincipalsPath(config):
|
||||||
|
try:
|
||||||
|
path = config.get('gitosis', 'ssh-principals-path')
|
||||||
|
except (NoSectionError, NoOptionError):
|
||||||
|
path = os.path.expanduser('~/.ssh/principals')
|
||||||
|
return path
|
||||||
|
|
Loading…
Reference in a new issue