Archive

Archive for May, 2009

Just small script for toying around with python….

May 12th, 2009

There is always a first time… now this is it.. in English coi…. :D
It happened during administrating servers in detik. Every time doing login to the servers, it always ask the password. There’s mechanism by copying public key into remote server in order to login automatically without entering the password. Application like ssh-copy-id do the job.
So, my concern is how to do login automatically without having explicitly launch ssh-copy-id before ssh to the server. I’ve written a script to handle that. This script requires pexpect library. Here it is :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""
USAGE:

go user@host

This script is used as One Time Password SSH login
"""


import os, pexpect, getpass, sys, socket
def gethomedir():
    for user in open('/etc/passwd'):
        cols = user.split(':')
        if cols[0] == os.getlogin():
            return cols[5]

def knownhost(user_host):
    for line in open(homedir + '/.ssh/hosts', 'a+'):
        if line.strip() == user_host:
            return True
    return False
           
def updateknownhost(user_host):
    fd = open(homedir + '/.ssh/hosts','a+')
    fd.write(user_host + '\n')
    fd.close()
   
if __name__ == "__main__":
    homedir = gethomedir()
    if not len(sys.argv) > 1 or sys.argv[1].find('@') < 0:
                print __doc__
                sys.exit(1)
   
    user,host = sys.argv[1].split('@')
    try:
        host = socket.gethostbyname(host)
    except socket.gaierror:
        print 'Error resolving host'
        sys.exit(1)
    if not knownhost(user + '@' + host):
        # ssh-copy-id and update info
        print 'Hostname %s | User %s' % (host, user)
        result = 0
        exp = pexpect.spawn('ssh-copy-id ' + sys.argv[1])
        while result != 2:
            result = exp.expect(['password', 'publickey,password', 'expecting', pexpect.EOF])
            if result == 0:
                # try again
                passwd = getpass.getpass('Enter Password:')
                exp.sendline(passwd)
            elif result == 1 or result == 3:
                # failed to input password correctly
                print 'Failed.'
                sys.exit(1)
        # update info
        updateknownhost(user + '@' + host)
        exp.close()
    os.system('ssh ' + ' '.join(sys.argv[1:]))

And also I’ve created small script to manipulate /etc/hosts, because sometime I don’t remember IP address of some servers, so I just need to create an alias in /etc/hosts. Here is the script :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
"""
USAGE:

hosts add address hostname... | del [address|hostname]...

This script adds/deletes hostname alias in /etc/hosts
"""


import os, getpass, sys, socket

lineread={}
linewrite={}

def addhosts(address, hostname):
        global linewrite, lineread
        notFound = True
        for idx, line in linewrite.iteritems():
                cols = filter(lambda x:not x == '', line.split())
                if cols[0] == address:
                        notFound = False
                        for host in hostname:
                                if not host in cols:
                                        cols.append(host)
                        linewrite[idx] = ' '.join(cols) + "\n"
        if notFound:
                lineread[len(lineread)] = address + ' ' + ' '.join(hostname) + "\n"

def delhosts(addr_host):
        global linewrite, lineread
        lw = linewrite.copy()
        isAddr = False
        for idx, line in lw.iteritems():
                cols = filter(lambda x:not x == '', line.split())
                for item in addr_host:
                        if item in cols:
                                if cols[0] == item:
                                        isAddr = True
                                        del linewrite[idx]
                                        del lineread[idx]
                                else:
                                        i = 1
                                        for col in cols[1:]:
                                                if col == item:
                                                        del cols[i]
                                                i+=1
                                        if len(cols) == 1:
                                                isAddr = True
                                                del linewrite[idx]
                                                del lineread[idx]
                if not isAddr:
                        linewrite[idx] = ' '.join(cols) + "\n"

if __name__ == "__main__":
        if not len(sys.argv) > 2 or not sys.argv[1] in ['add','del']:
                print __doc__
                sys.exit(1)

        idx=0
        try:
                for line in open('/etc/hosts'):
                        lineread[idx]=line
                        if not (line.strip().startswith('#')) and not (line.strip() == ''):
                                linewrite[idx]=line                    
                        idx+=1
        except IOError:
                print 'Error opening /etc/hosts'
                sys.exit(1)
       
        if sys.argv[1] == 'add':
                addhosts(sys.argv[2],sys.argv[3:])
        else:
                delhosts(sys.argv[2:])
       
        hosts = open('/etc/hosts','w')
        for idx, line in lineread.iteritems():
                if linewrite.has_key(idx):
                        hosts.write(linewrite[idx])
                else:
                        hosts.write(lineread[idx])

admin General