def generate_keys(seckey, userhost): logger.info('Generating new ssh keys...') rb = util.ReturnBox() sk = paramiko.RSAKey.generate(2048) try: sshdir = os.path.dirname(seckey) if not os.path.exists(sshdir): os.makedirs(sshdir) os.chmod(sshdir, 0o700) sk.write_private_key_file(seckey) except Exception as ex: logger.error(f'{ex}, {seckey}') rb.error = str(ex) return rb pubkey = f'ssh-rsa {sk.get_base64()} {userhost}' # try: # with open(seckey + '.pub', 'wt') as w: # w.write(pubkey) # except Exception as ex: # logger.error(f'Could not save public key: {ex}') rb.output = pubkey return rb
def testlogin(userhost, password, port=22): ''' Test ssh password authentication ''' logger.info(f'Logging in with password for {userhost}...') rb = util.ReturnBox() if not password: rb.returncode = util.ReturnCode.BAD_LOGIN rb.error = 'Empty password' return rb user, host = userhost.split('@') client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(hostname=host, username=user, password=password, port=port, timeout=10, look_for_keys=False) rb.returncode = util.ReturnCode.OK except (paramiko.ssh_exception.AuthenticationException, paramiko.ssh_exception.BadAuthenticationType, paramiko.ssh_exception.PasswordRequiredException) as ex: rb.returncode = util.ReturnCode.BAD_LOGIN rb.error = str(ex) except Exception as ex: rb.returncode = util.ReturnCode.BAD_HOST rb.error = str(ex) finally: client.close() return rb
def testhost(userhost, port=22): ''' Test if host respond to port Return: True or False ''' logger.info(f'Testing port {port} at {userhost}...') user, host = userhost.split('@') client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) rb = util.ReturnBox() try: client.connect(hostname=host, username=user, password='', port=port, timeout=5) rb.returncode = util.ReturnCode.OK except (paramiko.ssh_exception.AuthenticationException, paramiko.ssh_exception.BadAuthenticationType, paramiko.ssh_exception.PasswordRequiredException): rb.returncode = util.ReturnCode.OK except Exception as ex: rb.returncode = util.ReturnCode.BAD_HOST rb.error = str(ex) finally: client.close() return rb
def unmount_all(drives): for drive in drives: unmount(drive) rb = util.ReturnBox() rb.returncode = util.ReturnCode.OK return rb
def check_drive(sefl, p): rb = util.ReturnBox() rb.drive_status = mounter.check_drive(p['drive'], p['userhost']) if (rb.drive_status == 'CONNECTED' or rb.drive_status == 'DISCONNECTED'): rb.returncode = util.ReturnCode.OK return rb
def work(self, task, param): if self.slow: time.sleep(1) if hasattr(self, task): rb = getattr(self, task)(param) else: rb = util.ReturnBox('','Not implemented') self.workDone.emit(task, rb)
def unmount(drive): logger.info(f'Unmounting {drive}...') rb = util.ReturnBox() if not drive_is_valid(drive): rb.returncode = util.ReturnCode.BAD_DRIVE return rb util.kill_drive(drive) clean_drive(drive) rb.drive_status = 'DISCONNECTED' rb.returncode = util.ReturnCode.OK return rb
def connect(self, p): rb = util.ReturnBox() # check if winfsp is installed if not util.is_winfsp_installed(): rb.returncode = util.ReturnCode.BAD_WINFSP return rb # test drive status status = mounter.check_drive(p['drive'], p['userhost']) if status != 'DISCONNECTED': rb.returncode = util.ReturnCode.BAD_DRIVE rb.error = f'{status}' return rb # test ssh with app key rb = setupssh.testssh(p['userhost'], p['appkey'], p['port']) if rb.returncode != util.ReturnCode.OK: return rb # app keys are ok, mount return self.mount(p)
def main(userhost, password, port=22): ''' Setup ssh keys, return ReturnBox ''' logger.info(f'Setting up ssh keys for {userhost}...') rb = util.ReturnBox() # app key user, host = userhost.split('@') seckey = util.get_app_key(user) # Check if keys need to be generated pubkey = '' if has_app_keys(user): logger.info('Private key already exists.') sk = paramiko.RSAKey.from_private_key_file(seckey) pubkey = f'ssh-rsa {sk.get_base64()} {userhost}' else: rbkey = generate_keys(seckey, userhost) if rbkey.error: rbkey.returncode = util.ReturnCode.BAD_SSH return rbkey else: pubkey = rbkey.output # connect client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) rb.error = '' try: logger.info('Connecting using password...') client.connect(hostname=host, username=user, password=password, port=port, timeout=10, look_for_keys=False) except paramiko.ssh_exception.AuthenticationException: rb.error = f'User or password wrong' rb.returncode = 1 except Exception as ex: rb.error = f'connection error: {ex}' rb.returncode = 2 if rb.error: logger.error(rb.error) if 'getaddrinfo failed' in rb.error: rb.error = f'{host} not found' client.close() rb.returncode = util.ReturnCode.BAD_SSH return rb set_key_permissions(user, seckey) logger.info(f'Publising public key...') # Copy to the target machines. # cmd = f"exec bash -c \"cd; umask 077; mkdir -p .ssh && echo '{pubkey}' >> .ssh/authorized_keys || exit 1\" || exit 1" cmd = f"exec sh -c \"cd; umask 077; mkdir -p .ssh; echo '{pubkey}' >> .ssh/authorized_keys\"" logger.info(cmd) ok = False try: stdin, stdout, stderr = client.exec_command(cmd, timeout=10) rc = stdout.channel.recv_exit_status() if rc == 0: logger.info('Key transfer successful') rb.returncode = util.ReturnCode.OK else: logger.error( f'Error transfering public key: exit {rc}, error: {stderr}') except Exception as ex: logger.error(ex) rb.returncode = util.ReturnCode.BAD_SSH rb.error = f'error transfering public key: {ex}' return rb finally: client.close() err = stderr.read() if err: logger.error(err) rb.returncode = util.ReturnCode.BAD_SSH rb.error = f'error transfering public key, error: {err}' return rb rb = testssh(userhost, seckey, port) if rb.returncode == util.ReturnCode.OK: rb.output = "SSH setup successfull." logger.info(rb.output) else: message = 'SSH setup test failed' detail = '' if rb.returncode == util.ReturnCode.BAD_LOGIN: detail = ': authentication probem' else: message = ': connection problem' rb.error = message rb.returncode = util.ReturnCode.BAD_SSH logger.error(message + detail) return rb
def mount(drive, userhost, appkey, port=22, drivename='', args=''): logger.info(f'Mounting {drive} {userhost}...') rb = util.ReturnBox() user, host = userhost.split('@') letter = drive.strip(':') if not drivename: drivename = 'GOLDDRIVE' # result = setupssh.testssh(ssh, userhost, appkey, port) # if result == util.ReturnCode.BAD_LOGIN: # rb.error = 'SSH key authetication wrong' # rb.drive_status = 'KEYS_WRONG' # rb.returncode = result # return rb status = check_drive(drive, userhost) if not status == 'DISCONNECTED': rb.error = status rb.drive_status = status return rb cmd = f'''golddrive.exe {drive} -o host={host} -o user={user} -o port={port} -o pkey={appkey} -o uid=-1,gid=-1,create_umask=007,mask=007 ''' # else: # cmd = f'''sshfs.exe {userhost}:/ {drive} # -o port={port} # -o IdentityFile={appkey} # -o VolumePrefix=/sshfs/{userhost} # -o volname={userhost} # -o uid=-1,gid=-1,create_umask=007,mask=007 # -o FileSystemName=SSHFS # -o PasswordAuthentication=no # -o StrictHostKeyChecking=no # -o UserKnownHostsFile=/dev/null # -o ServerAliveInterval=60 # -o compression=no # -o rellinks # -o reconnect # ''' # # -o max_read=65536 # # -o max_write=65536 # # -o sshfs_sync # # -f # # -o ThreadCount=10 # # -o dir_cache=yes # # -o dcache_timeout=5 # # -o dcache_clean_interval=300 # # -o KeepFileCache # # -o FileInfoTimeout=-1 # # -o DirInfoTimeout=5000 # # -o VolumeInfoTimeout=5000 # # -o [email protected] # # -o ServerAliveCountMax=10000 # # -o ssh_command='ssh -vv -d' # fuse_opts = ''' # -o FileInfoTimeout=3000 # -o DirInfoTimeout=5000 # -o VolumeInfoTimeout=10000 # ''' cmd = cmd.replace('\n',' ').replace('\r','').replace('\t','') cmd += ' ' + args # logger.info(cmd) util.run(cmd, detach=True) # proc = subprocess.Popen(cmd, shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) time.sleep(1) set_drive_name(drivename, drive) set_net_use(drive) set_drive_icon(drive) rb.drive_status = 'CONNECTED' rb.returncode = util.ReturnCode.OK return rb
def restart_explorer(self, p): util.restart_explorer() return util.ReturnBox('Explorer.exe was restarted','')