--- /dev/null
+import os.path
+
+import commands
+import os
+import pwd
+import settings
+import socket
+import sys
+
+import paramiko
+
+from backup.pcsbackuputils import createFolder
+
+sshPath = os.path.expanduser('~/.ssh/')
+known_hosts = os.path.join(sshPath, 'known_hosts')
+log_file = os.path.expanduser('~/.pcsuite/.ssh_log')
+user = 'root'
+keyName = 'rsa_key'
+
+def create_route(host, port=22):
+ # Verify Auth with privateKey
+ try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.settimeout(15)
+ sock.connect((host, port))
+ sock.close()
+ return True
+ except:
+ print 'No route to host'
+ return False
+
+def verify_exist_keys(host, port=22):
+ try:
+ transport = _create_transport(host, port)
+ except:
+ return False
+ try:
+ getKey = paramiko.RSAKey.from_private_key_file(sshPath + keyName)
+ transport.start_client()
+ transport.auth_publickey(user, getKey)
+ if transport.is_authenticated():
+ transport.close()
+ return True
+ except:
+ # 'Error in auth with publickey, try with password...'
+ return False
+ return False
+
+def keyExchange(host, passwd, port=22):
+ if not os.path.exists(sshPath):
+ createFolder(sshPath)
+
+ # Clean cached keys in ssh-agent
+ os.system('ssh-add -d')
+
+ try:
+ transport = _create_transport(host, port)
+ except:
+ transport.close()
+ return False
+
+ if not _add_host_fingerprint(host):
+ transport.close()
+ return False
+
+ if not _authenticate(user, passwd, transport):
+ transport.close()
+ return False
+
+ if not _add_key_to_host(host, transport):
+ transport.close()
+ return False
+
+ transport.stop_thread()
+ transport.close()
+ return True
+
+def initDirs():
+ settings.makeDirs()
+
+def _create_transport(host, port):
+ # Create a transport and initiate client mode
+ try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.settimeout(15)
+ sock.connect((host, port))
+ except Exception, msg:
+ print 'Connect failed: ' + str(msg)
+ raise Exception('Error while create sockets.')
+ transport = paramiko.Transport(sock)
+ return transport
+
+def _add_host_fingerprint(host):
+ if not os.path.exists(known_hosts):
+ os.system('touch %s' %known_hosts)
+ if os.system('ssh-keyscan -t rsa %s >> %s' %(host, known_hosts)) != 0:
+ return False
+ return True
+
+def _generate_keys():
+ # Generate public and private RSAKey
+ keyFile = os.path.join(sshPath, keyName)
+ if not os.path.exists(keyFile):
+ privateKey = paramiko.RSAKey.generate(2048)
+ privateKey.write_private_key_file(keyFile)
+ login = pwd.getpwuid(os.geteuid())[0]
+ publicKey = '%s %s %s@%s' %(privateKey.get_name(),
+ privateKey.get_base64(),
+ login , socket.gethostname())
+ try:
+ keyFile = open(keyFile + '.pub','w')
+ keyFile.write(publicKey)
+ keyFile.close()
+ except:
+ print 'Error while save the public key'
+ raise Exception()
+ else:
+ try:
+ privateKey = paramiko.RSAKey.from_private_key_file(keyFile)
+ login = pwd.getpwuid(os.geteuid())[0]
+ publicKey = '%s %s %s@%s' %(privateKey.get_name(),
+ privateKey.get_base64(),
+ login , socket.gethostname())
+ except:
+ print 'Error while read the private key'
+ raise Exception()
+ return publicKey
+
+def _authenticate(user, passwd, transport):
+ # Try Auth with password
+ try:
+ transport.start_client()
+ transport.auth_password(user, passwd)
+ except:
+ print 'Verify user or password.'
+ return False
+ if not transport.is_authenticated():
+ print 'Authentication fail'
+ return False
+
+ try:
+ exception = transport.get_exception()
+ if exception:
+ raise exception
+ except Exception, msg:
+ print 'Error in connection: ' + str(msg)
+ return False
+ return True
+
+def _add_key_to_host(host, transport):
+ # Add publickey in host
+ if not transport.is_active():
+ print 'Channel is not active'
+ return False
+
+ paramiko.util.log_to_file(log_file, 10)
+ channel = transport.open_session()
+ try:
+ channel.exec_command('mkdir -p ~/.ssh; echo %s >> .ssh/authorized_keys' % (_generate_keys()))
+ except Exception, msg:
+ print 'Error while generate or add the keys.'
+ channel.close()
+ return False
+ channel.close()
+ return True