src/mercurialserver/refreshauth.py
author Paul Crowley <paul@lshift.net>
Sat, 07 Mar 2009 09:48:10 +0000
changeset 85 80fa761c7f5d
parent 79 3a58a95fae2f
child 86 78777f509303
permissions -rw-r--r--
Safety check must actually exit
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     1
# Copyright 2008-2009 LShift Ltd
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     2
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     3
# WARNING
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     4
# This hook completely destroys your ~/.ssh/authorized_keys
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     5
# file every time it is run
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     6
# WARNING
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     7
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     8
import sys
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     9
import os
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    10
import os.path
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    11
import pwd
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    12
import subprocess
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    13
from mercurialserver import ruleset, paths
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    14
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    15
def refreshAuth():
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    16
    pentry = pwd.getpwuid(os.geteuid())
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    17
    if pentry.pw_name != "hg":
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    18
        # FIXME: re-execute
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    19
        print >>sys.stderr, "Must be run as the 'hg' user"
85
80fa761c7f5d Safety check must actually exit
Paul Crowley <paul@lshift.net>
parents: 79
diff changeset
    20
        sys.exit(-1)
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    21
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    22
    akeyfile = pentry.pw_dir + "/.ssh/authorized_keys"
79
3a58a95fae2f abolish hg-ssh-wrapper
Paul Crowley <paul@lshift.net>
parents: 75
diff changeset
    23
    wrappercommand = paths.getExePath() + "/hg-ssh"
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    24
    keydirs = [paths.getEtcPath() + "/keys", pentry.pw_dir + "/repos/hgadmin/keys"]
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    25
    prefix='no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command='
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    26
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    27
    if os.path.exists(akeyfile):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    28
        f = open(akeyfile)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    29
        try:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    30
            for l in f:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    31
                if not l.startswith(prefix):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    32
                    raise Exception("Safety check failed, delete %s to continue" % akeyfile)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    33
        finally:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    34
            f.close()
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    35
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    36
    akeys = open(akeyfile + "_new", "w")
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    37
    for keyroot in keydirs:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    38
        kr = keyroot + "/"
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    39
        #print "Processing keyroot", keyroot
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    40
        for root, dirs, files in os.walk(keyroot):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    41
            for fn in files:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    42
                ffn = os.path.join(root, fn)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    43
                if not ffn.startswith(kr):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    44
                    raise Exception("Inconsistent behaviour in os.walk, bailing")
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    45
                #print "Processing file", ffn
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    46
                keyname = ffn[len(kr):]
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    47
                if not ruleset.goodpath(keyname):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    48
                    # ignore any path that contains dodgy characters
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    49
                    #print "Ignoring file", ffn
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    50
                    continue
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    51
                p = subprocess.Popen(("ssh-keygen", "-i", "-f", ffn), 
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    52
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    53
                newkey = p.communicate()[0]
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    54
                if p.wait() == 0:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    55
                    klines = [l.strip() for l in newkey.split("\n")]
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    56
                else:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    57
                    # Conversion failed, read it directly.
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    58
                    kf = open(ffn)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    59
                    try:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    60
                        klines = [l.strip() for l in kf]
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    61
                    finally:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    62
                        kf.close()
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    63
                for l in klines:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    64
                    if len(l):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    65
                        akeys.write('%s"%s %s" %s\n' % (prefix, wrappercommand, keyname, l))
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    66
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    67
    akeys.close()
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    68
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    69
    os.rename(akeyfile + "_new", akeyfile)
75
5af89523a9d3 give refreshauth.py a hook and call that in hgadmin hgrc
Paul Crowley <paul@lshift.net>
parents: 74
diff changeset
    70
    
5af89523a9d3 give refreshauth.py a hook and call that in hgadmin hgrc
Paul Crowley <paul@lshift.net>
parents: 74
diff changeset
    71
def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
5af89523a9d3 give refreshauth.py a hook and call that in hgadmin hgrc
Paul Crowley <paul@lshift.net>
parents: 74
diff changeset
    72
    refreshAuth()
5af89523a9d3 give refreshauth.py a hook and call that in hgadmin hgrc
Paul Crowley <paul@lshift.net>
parents: 74
diff changeset
    73