Last update of gforge repository
[tablet-suite] / src / pcsutils.py
1 import os.path
2
3 import commands
4 import os
5 import pwd
6 import settings
7 import socket
8 import sys
9
10 import paramiko
11
12 from backup.pcsbackuputils import createFolder
13
14 sshPath = os.path.expanduser('~/.ssh/') 
15 known_hosts = os.path.join(sshPath, 'known_hosts')
16 log_file = os.path.expanduser('~/.pcsuite/.ssh_log')
17 user = 'root'
18 keyName = 'rsa_key'
19
20 def create_route(host, port=22):
21     # Verify Auth with privateKey
22     try:
23         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
24         sock.settimeout(15)
25         sock.connect((host, port))
26         sock.close()
27         return True
28     except:
29         print 'No route to host'
30         return False
31
32 def verify_exist_keys(host, port=22):
33     try:    
34         transport = _create_transport(host, port)
35     except:
36         return False
37     try:
38         getKey = paramiko.RSAKey.from_private_key_file(sshPath + keyName)
39         transport.start_client()
40         transport.auth_publickey(user, getKey)
41         if transport.is_authenticated():
42             transport.close()
43             return True
44     except:
45         # 'Error in auth with publickey, try with password...'
46         return False
47     return False
48
49 def keyExchange(host, passwd, port=22):
50     if not os.path.exists(sshPath):
51         createFolder(sshPath)
52
53     # Clean cached keys in ssh-agent
54     os.system('ssh-add -d')    
55
56     try:
57         transport = _create_transport(host, port)
58     except:
59         transport.close()
60         return False
61
62     if not _add_host_fingerprint(host):
63         transport.close()
64         return False
65
66     if not _authenticate(user, passwd, transport):
67         transport.close()
68         return False
69     
70     if not _add_key_to_host(host, transport):
71         transport.close()
72         return False
73
74     transport.stop_thread()
75     transport.close()
76     return True
77
78 def initDirs():
79     settings.makeDirs()
80
81 def _create_transport(host, port):
82     # Create a transport and initiate client mode
83     try:
84         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
85         sock.settimeout(15)
86         sock.connect((host, port))
87     except Exception, msg:
88         print 'Connect failed: ' + str(msg)
89         raise Exception('Error while create sockets.')
90     transport = paramiko.Transport(sock)
91     return transport
92
93 def _add_host_fingerprint(host):
94     if not os.path.exists(known_hosts):
95         os.system('touch %s' %known_hosts)
96     if os.system('ssh-keyscan -t rsa %s >> %s' %(host, known_hosts)) != 0:
97         return False
98     return True
99
100 def _generate_keys():
101     # Generate public and private RSAKey
102     keyFile = os.path.join(sshPath, keyName)
103     if not os.path.exists(keyFile):
104         privateKey = paramiko.RSAKey.generate(2048)
105         privateKey.write_private_key_file(keyFile)
106         login = pwd.getpwuid(os.geteuid())[0]
107         publicKey = '%s %s %s@%s' %(privateKey.get_name(), 
108                                     privateKey.get_base64(),
109                                     login , socket.gethostname())
110         try:
111             keyFile = open(keyFile + '.pub','w')
112             keyFile.write(publicKey)
113             keyFile.close()
114         except:
115             print 'Error while save the public key'
116             raise Exception()
117     else:
118         try:
119             privateKey = paramiko.RSAKey.from_private_key_file(keyFile)
120             login = pwd.getpwuid(os.geteuid())[0]
121             publicKey = '%s %s %s@%s' %(privateKey.get_name(), 
122                                         privateKey.get_base64(),
123                                     login , socket.gethostname())
124         except:
125             print 'Error while read the private key'
126             raise Exception()
127     return publicKey
128
129 def _authenticate(user, passwd, transport):
130     # Try Auth with password
131     try:
132         transport.start_client()
133         transport.auth_password(user, passwd)
134     except:
135         print 'Verify user or password.'
136         return False
137     if not transport.is_authenticated():
138         print 'Authentication fail'
139         return False
140
141     try:
142         exception = transport.get_exception()
143         if exception:
144             raise exception
145     except Exception, msg:
146         print 'Error in connection: ' + str(msg)
147         return False
148     return True
149
150 def _add_key_to_host(host, transport):
151     # Add publickey in host
152     if not transport.is_active():
153         print 'Channel is not active'
154         return False
155     
156     paramiko.util.log_to_file(log_file, 10)
157     channel = transport.open_session()
158     try:
159         channel.exec_command('mkdir -p ~/.ssh; echo %s >> .ssh/authorized_keys' % (_generate_keys()))
160     except Exception, msg:
161         print 'Error while generate or add the keys.'
162         channel.close()
163         return False
164     channel.close()
165     return True