src/mercurialserver/refreshauth.py
author Paul Crowley <paul@lshift.net>
Tue, 06 Sep 2011 10:58:57 +0100
changeset 309 091630a3938e
parent 260 57dcdb212d00
child 311 3cbde66305e4
permissions -rw-r--r--
Use old-style qinit for mercurial 1.0 compatibility
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
242
03d8f07230b3 Tidy up file prologues; move credits to CREDITS
Paul Crowley <paul@lshift.net>
parents: 213
diff changeset
     1
"""
03d8f07230b3 Tidy up file prologues; move credits to CREDITS
Paul Crowley <paul@lshift.net>
parents: 213
diff changeset
     2
Rewrite ~/.ssh/authorized_keys by recursing through key directories
03d8f07230b3 Tidy up file prologues; move credits to CREDITS
Paul Crowley <paul@lshift.net>
parents: 213
diff changeset
     3
"""
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     4
106
0519745e7a57 Much less strict about most things
Paul Crowley <paul@lshift.net>
parents: 86
diff changeset
     5
import re
107
84e9e33d866b Fixes, plus base64 what you don't trust
Paul Crowley <paul@lshift.net>
parents: 106
diff changeset
     6
import base64
260
57dcdb212d00 Fix permissions of authorized_keys file for sshd StrictModes
Steven King <kingrst@gmail.com>
parents: 242
diff changeset
     7
import os, stat
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     8
import os.path
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
     9
import subprocess
211
0cd59649772c Rename paths.py ot config.py
Paul Crowley <paul@lshift.net>
parents: 165
diff changeset
    10
from mercurialserver import config
106
0519745e7a57 Much less strict about most things
Paul Crowley <paul@lshift.net>
parents: 86
diff changeset
    11
107
84e9e33d866b Fixes, plus base64 what you don't trust
Paul Crowley <paul@lshift.net>
parents: 106
diff changeset
    12
goodkey = re.compile("[/A-Za-z0-9._-]+$")
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    13
165
3606d60b07e5 Use .mercurial-sever file instead of hardcoding
Paul Crowley <paul@lshift.net>
parents: 107
diff changeset
    14
def refreshAuth():
213
72e7ba8b41a6 Don't hardwire location of authorized_keys file
Paul Crowley <paul@lshift.net>
parents: 211
diff changeset
    15
    akeyfile = config.getAuthorizedKeysPath()
211
0cd59649772c Rename paths.py ot config.py
Paul Crowley <paul@lshift.net>
parents: 165
diff changeset
    16
    wrappercommand = config.getExePath() + "/hg-ssh"
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    17
    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
    18
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    19
    if os.path.exists(akeyfile):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    20
        f = open(akeyfile)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    21
        try:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    22
            for l in f:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    23
                if not l.startswith(prefix):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    24
                    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
    25
        finally:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    26
            f.close()
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    27
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    28
    akeys = open(akeyfile + "_new", "w")
211
0cd59649772c Rename paths.py ot config.py
Paul Crowley <paul@lshift.net>
parents: 165
diff changeset
    29
    for keyroot in config.getKeysPaths():
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    30
        kr = keyroot + "/"
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    31
        #print "Processing keyroot", keyroot
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    32
        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
    33
            for fn in files:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    34
                ffn = os.path.join(root, fn)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    35
                if not ffn.startswith(kr):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    36
                    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
    37
                #print "Processing file", ffn
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    38
                keyname = ffn[len(kr):]
107
84e9e33d866b Fixes, plus base64 what you don't trust
Paul Crowley <paul@lshift.net>
parents: 106
diff changeset
    39
                if not goodkey.match(keyname):
84e9e33d866b Fixes, plus base64 what you don't trust
Paul Crowley <paul@lshift.net>
parents: 106
diff changeset
    40
                    # Encode it for safe quoting
84e9e33d866b Fixes, plus base64 what you don't trust
Paul Crowley <paul@lshift.net>
parents: 106
diff changeset
    41
                    keyname = "--base64 " + base64.b64encode(keyname)
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    42
                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
    43
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    44
                newkey = p.communicate()[0]
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    45
                if p.wait() == 0:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    46
                    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
    47
                else:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    48
                    # Conversion failed, read it directly.
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    49
                    kf = open(ffn)
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    50
                    try:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    51
                        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
    52
                    finally:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    53
                        kf.close()
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    54
                for l in klines:
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    55
                    if len(l):
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    56
                        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
    57
    akeys.close()
260
57dcdb212d00 Fix permissions of authorized_keys file for sshd StrictModes
Steven King <kingrst@gmail.com>
parents: 242
diff changeset
    58
    os.chmod(akeyfile + "_new", stat.S_IRUSR)
74
9d2ae2841bf2 Move meat of do-refresh-auth into a module
Paul Crowley <paul@lshift.net>
parents:
diff changeset
    59
    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
    60
    
5af89523a9d3 give refreshauth.py a hook and call that in hgadmin hgrc
Paul Crowley <paul@lshift.net>
parents: 74
diff changeset
    61
def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
165
3606d60b07e5 Use .mercurial-sever file instead of hardcoding
Paul Crowley <paul@lshift.net>
parents: 107
diff changeset
    62
    refreshAuth()
75
5af89523a9d3 give refreshauth.py a hook and call that in hgadmin hgrc
Paul Crowley <paul@lshift.net>
parents: 74
diff changeset
    63