#!/usr/bin/python3
# 
# This script updates the login keys for ssh and inserts itself into the daily cron
# If you have the updated script, then you have the updated keys via svn in 
# /usr/local/afribin/ssh/*.pub
#
# Anything in /root/.ssh/authorized_keys2_static will also get included into authorized_keys2
# /root/.ssh/authorized_keys is left alone

import os,os.path,sys
import tempfile,random,signal

hostname=None

def newline(s):
    if s and s[-1]!="\n":
        return s+"\n"
    return s

def afrihost_managed_cpanel():
    if open("/etc/ssh/sshd_config",'r').read().find("\nPort 24") == -1: return False
    if not os.path.exists("/var/cpanel/users"): return False
    return True

def gethostname():
    global hostname
    if not hostname:
        hostname = os.popen("hostname",'r').read().strip();
    return hostname


class SystemAlarm(Exception):
    """Used for handling signal.alarm calls, mostly to control lock timeouts"""
    def __init__(self, value = "Timed Out"):
        self.value = value
    def __str__(self):
        return repr(self.value)

def alarm_handler(signum, frame): 
    raise SystemAlarm
signal.signal(signal.SIGALRM, alarm_handler)

###############################################################################
what_changed = None

try:
    keytime = os.stat("/root/.ssh/authorized_keys2") . st_ctime;
except OSError:
    keytime = 0;

public_keys="";
hostname = gethostname()
is_afrihost_server = hostname.find("afrihost.co")>=0
is_dedicated_server = hostname.find("dedicated.co.za") >0 or \
    hostname.find("lumberjack") >=0 
is_backup_server = hostname.find("backup")==0
is_afrihost_managed_cpanel = afrihost_managed_cpanel() and not is_afrihost_server

# Build list, and check mod time
keydir = "/usr/local/afribin/ssh"
for pubfile in os.listdir(keydir):
    if (not pubfile.endswith(".pub")): continue
    pubfile=keydir+"/"+pubfile
    keys=open(pubfile,"r").read()
    if is_afrihost_managed_cpanel or \
        (is_dedicated_server and keys.find("@dedi")>0)  or \
        (is_backup_server and keys.find("@back")>0)  or \
        keys.find("@admin")>0: # admin for administrators
        public_keys+=newline(keys)


if not os.path.exists("/root/.ssh"):
    os.mkdir("/root/.ssh")
staticfile = "/root/.ssh/authorized_keys2_static"
if os.path.exists(staticfile):
    public_keys+=newline(open(staticfile,"r").read())

keyfile = "/root/.ssh/authorized_keys2"
if os.path.exists(keyfile):
    content=newline(open(keyfile,'r').read())
else:
    content=''

if content != public_keys:
    out=open(keyfile,"w")
    out.write(public_keys)
    out.close()

###############################################################################
#Install ourself into daily cron
updatecmd="/usr/local/afribin/sshkeysupdate"

cron=[]
updatefound=0
for line in os.popen("crontab -l -u root","r").readlines():
    line=line.strip()
    cron.append(line)
    if line.find(updatecmd) > -1: updatefound=1
if not updatefound: 
    # Update crontab
    cron.append("")
    cron.append("#Update system with the afrihost ssh keys.")
    cron.append("#Comment out (DO NOT DELETE) the command below to disable")
    cron.append("%s %s * * * %s" % (random.randint(0,59),random.randint(0,23),updatecmd))
    cron.append("#if you just delete it, your changes will be overwritten")

    try: (h,fname)=tempfile.mkstemp()
    except AttributeError: #Doh, old version of python
        fname=tempfile.mktemp()
    f=open(fname,"w")
    f.write("\n".join(cron))
    f.write("\n")
    f.close()
    os.system("crontab -u root %s" % (fname)) #Load the changes into the cron

