def success(event): if (event.GetId() == KeyDist.EVT_KEYDIST_AUTHSUCCESS): logger_debug("received AUTHSUCCESS event") event.keydist.completed=True if (event.keydist.callback_success != None): event.keydist.callback_success() event.Skip()
def authfail(event): if (event.GetId() == KeyDist.EVT_KEYDIST_AUTHFAIL): logger_debug("received AUTHFAIL event") event.keydist.pubkeylock.acquire() keyloaded = event.keydist.keyloaded event.keydist.pubkeylock.release() if(not keyloaded): newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_LOADKEY,event.keydist) wx.PostEvent(event.keydist.notifywindow.GetEventHandler(),newevent) else: # if they key is loaded into the ssh agent, then authentication failed because the public key isn't on the server. # *****TODO***** # actually this might not be strictly true. gnome keychain (and possibly others) will report a key loaded even if its still locked # we probably need a button that says "I can't remember my old keys password, please generate a new keypair" event.keydist.keycopiedLock.acquire() keycopied=event.keydist.keycopied event.keydist.keycopiedLock.release() if (keycopied): newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_TESTAUTH,event.keydist) wx.PostEvent(event.keydist.notifywindow.GetEventHandler(),newevent) else: newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_COPYID_NEEDPASS,event.keydist) wx.PostEvent(event.keydist.notifywindow.GetEventHandler(),newevent) else: event.Skip()
def run(self): sshClient = ssh.SSHClient() sshClient.set_missing_host_key_policy(ssh.AutoAddPolicy()) try: sshClient.connect(hostname=self.keydistObject.host,username=self.keydistObject.username,password=self.keydistObject.password,allow_agent=False,look_for_keys=False) sshClient.exec_command("module load massive") sshClient.exec_command("/bin/mkdir -p ~/.ssh") sshClient.exec_command("/bin/chmod 700 ~/.ssh") sshClient.exec_command("/bin/touch ~/.ssh/authorized_keys") sshClient.exec_command("/bin/chmod 600 ~/.ssh/authorized_keys") sshClient.exec_command("/bin/echo \"%s\" >> ~/.ssh/authorized_keys"%self.keydistObject.pubkey) # FIXME The exec_commands above can fail if the user is over quota. sshClient.close() self.keydistObject.keycopiedLock.acquire() self.keydistObject.keycopied=True self.keydistObject.keycopiedLock.release() event = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_TESTAUTH,self.keydistObject) logger_debug('CopyIDThread: successfully copied the key') except socket.gaierror as e: logger_debug('CopyIDThread: socket.gaierror : ' + str(e)) self.keydistObject.cancel(message=str(e)) return except socket.error as e: logger_debug('CopyIDThread: socket.error : ' + str(e)) self.keydistObject.cancel(message=str(e)) return except ssh.AuthenticationException as e: logger_debug('CopyIDThread: ssh.AuthenticationException: ' + str(e)) event = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_COPYID_NEEDPASS,self.keydistObject,str(e)) except ssh.SSHException as e: logger_debug('CopyIDThread: ssh.SSHException : ' + str(e)) self.keydistObject.cancel(message=str(e)) return if (not self.stopped()): wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), event)
def startevent(event): if (event.GetId() == KeyDist.EVT_KEYDIST_START): logger_debug("received KEYDIST_START event") newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_SCANHOSTKEYS,event.keydist) wx.PostEvent(event.keydist.notifywindow.GetEventHandler(),newevent) else: event.Skip()
def success(event): if (event.GetId() == KeyDist.EVT_KEYDIST_AUTHSUCCESS): logger_debug("received AUTHSUCCESS event") event.keydist.completed = True if (event.keydist.callback_success != None): event.keydist.callback_success() event.Skip()
def authfail(event): if (event.GetId() == KeyDist.EVT_KEYDIST_AUTHFAIL): logger_debug("received AUTHFAIL event") event.keydist.pubkeylock.acquire() keyloaded = event.keydist.keyloaded event.keydist.pubkeylock.release() if (not keyloaded): newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_LOADKEY, event.keydist) wx.PostEvent(event.keydist.notifywindow.GetEventHandler(), newevent) else: # if they key is loaded into the ssh agent, then authentication failed because the public key isn't on the server. # *****TODO***** # actually this might not be strictly true. gnome keychain (and possibly others) will report a key loaded even if its still locked # we probably need a button that says "I can't remember my old keys password, please generate a new keypair" event.keydist.keycopiedLock.acquire() keycopied = event.keydist.keycopied event.keydist.keycopiedLock.release() if (keycopied): newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_TESTAUTH, event.keydist) wx.PostEvent( event.keydist.notifywindow.GetEventHandler(), newevent) else: newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_COPYID_NEEDPASS, event.keydist) wx.PostEvent( event.keydist.notifywindow.GetEventHandler(), newevent) else: event.Skip()
def cancel(self, message=""): if (not self.canceled()): self._canceled.set() newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_CANCEL, self) logger_debug('Sending EVT_KEYDIST_CANCEL event.') wx.PostEvent(self.notifywindow.GetEventHandler(), newevent)
def scanhostkeys(event): if (event.GetId() == KeyDist.EVT_KEYDIST_SCANHOSTKEYS): logger_debug("recieved SCANHOSTKEYS event") t = KeyDist.scanHostKeysThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) event.Skip()
def keylocked(event): if (event.GetId() == KeyDist.EVT_KEYDIST_KEY_LOCKED): logger_debug("received KEY_LOCKED event") wx.CallAfter(event.keydist.GetKeyPassword) if (event.GetId() == KeyDist.EVT_KEYDIST_KEY_WRONGPASS): logger_debug("received KEY_WRONGPASS event") wx.CallAfter(event.keydist.GetKeyPassword,"Sorry that password was incorrect. ") event.Skip()
def listpubkeys(event): if (event.GetId() == KeyDist.EVT_KEYDIST_GETPUBKEY): logger_debug("received GETPUBKEY event") t = KeyDist.getPubKeyThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def needagent(event): if (event.GetId() == KeyDist.EVT_KEYDIST_NEEDAGENT): logger_debug("received NEEDAGENT event") t = KeyDist.startAgentThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def startevent(event): if (event.GetId() == KeyDist.EVT_KEYDIST_START): logger_debug("received KEYDIST_START event") newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_SCANHOSTKEYS, event.keydist) wx.PostEvent(event.keydist.notifywindow.GetEventHandler(), newevent) else: event.Skip()
def keylocked(event): if (event.GetId() == KeyDist.EVT_KEYDIST_KEY_LOCKED): logger_debug("received KEY_LOCKED event") wx.CallAfter(event.keydist.GetKeyPassword) if (event.GetId() == KeyDist.EVT_KEYDIST_KEY_WRONGPASS): logger_debug("received KEY_WRONGPASS event") wx.CallAfter(event.keydist.GetKeyPassword, "Sorry that password was incorrect. ") event.Skip()
def loadkey(event): if (event.GetId() == KeyDist.EVT_KEYDIST_LOADKEY): logger_debug("received LOADKEY event") t = KeyDist.loadKeyThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def testauth(event): if (event.GetId() == KeyDist.EVT_KEYDIST_TESTAUTH): logger_debug("received TESTAUTH event") logger_debug("received TESTAUTH event, starting testAuthThread") t = KeyDist.testAuthThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def onEnter(self, e): self.canceled = True if (e.GetId() == self.Cancel.GetId()): logger_debug('onEnter: canceled = True') self.canceled = True self.password = None else: logger_debug('onEnter: canceled = False') self.canceled = False self.password = self.PassphraseField.GetValue() self.Close()
def onEnter(self,e): self.canceled=True if (e.GetId() == self.Cancel.GetId()): logger_debug('onEnter: canceled = True') self.canceled = True self.password = None else: logger_debug('onEnter: canceled = False') self.canceled = False self.password = self.PassphraseField.GetValue() self.Close()
def testauth(event): if (event.GetId() == KeyDist.EVT_KEYDIST_TESTAUTH): logger_debug("received TESTAUTH event") logger_debug( "received TESTAUTH event, starting testAuthThread") t = KeyDist.testAuthThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def copyid(event): if (event.GetId() == KeyDist.EVT_KEYDIST_COPYID_NEEDPASS): logger_debug("recieved COPYID_NEEDPASS event") wx.CallAfter(event.keydist.getLoginPassword,event.string) elif (event.GetId() == KeyDist.EVT_KEYDIST_COPYID): logger_debug("recieved COPYID event") t = KeyDist.CopyIDThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def copyid(event): if (event.GetId() == KeyDist.EVT_KEYDIST_COPYID_NEEDPASS): logger_debug("recieved COPYID_NEEDPASS event") wx.CallAfter(event.keydist.getLoginPassword, event.string) elif (event.GetId() == KeyDist.EVT_KEYDIST_COPYID): logger_debug("recieved COPYID event") t = KeyDist.CopyIDThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) else: event.Skip()
def run(self): sshClient = ssh.SSHClient() sshClient.set_missing_host_key_policy(ssh.AutoAddPolicy()) try: sshClient.connect(hostname=self.keydistObject.host, username=self.keydistObject.username, password=self.keydistObject.password, allow_agent=False, look_for_keys=False) sshClient.exec_command("module load massive") sshClient.exec_command("/bin/mkdir -p ~/.ssh") sshClient.exec_command("/bin/chmod 700 ~/.ssh") sshClient.exec_command("/bin/touch ~/.ssh/authorized_keys") sshClient.exec_command("/bin/chmod 600 ~/.ssh/authorized_keys") sshClient.exec_command( "/bin/echo \"%s\" >> ~/.ssh/authorized_keys" % self.keydistObject.pubkey) # FIXME The exec_commands above can fail if the user is over quota. sshClient.close() self.keydistObject.keycopiedLock.acquire() self.keydistObject.keycopied = True self.keydistObject.keycopiedLock.release() event = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_TESTAUTH, self.keydistObject) logger_debug('CopyIDThread: successfully copied the key') except socket.gaierror as e: logger_debug('CopyIDThread: socket.gaierror : ' + str(e)) self.keydistObject.cancel(message=str(e)) return except socket.error as e: logger_debug('CopyIDThread: socket.error : ' + str(e)) self.keydistObject.cancel(message=str(e)) return except ssh.AuthenticationException as e: logger_debug('CopyIDThread: ssh.AuthenticationException: ' + str(e)) event = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_COPYID_NEEDPASS, self.keydistObject, str(e)) except ssh.SSHException as e: logger_debug('CopyIDThread: ssh.SSHException : ' + str(e)) self.keydistObject.cancel(message=str(e)) return if (not self.stopped()): wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), event)
def newkey(event): if (event.GetId() == KeyDist.EVT_KEYDIST_NEWPASS_REQ): logger_debug("recieved NEWPASS_REQ event") wx.CallAfter(event.keydist.getNewPassphrase_stage1,event.string) if (event.GetId() == KeyDist.EVT_KEYDIST_NEWPASS_RPT): logger_debug("recieved NEWPASS_RPT event") wx.CallAfter(event.keydist.getNewPassphrase_stage2) if (event.GetId() == KeyDist.EVT_KEYDIST_NEWPASS_COMPLETE): logger_debug("recieved NEWPASS_COMPLETE event") t = KeyDist.genkeyThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) event.Skip()
def newkey(event): if (event.GetId() == KeyDist.EVT_KEYDIST_NEWPASS_REQ): logger_debug("recieved NEWPASS_REQ event") wx.CallAfter(event.keydist.getNewPassphrase_stage1, event.string) if (event.GetId() == KeyDist.EVT_KEYDIST_NEWPASS_RPT): logger_debug("recieved NEWPASS_RPT event") wx.CallAfter(event.keydist.getNewPassphrase_stage2) if (event.GetId() == KeyDist.EVT_KEYDIST_NEWPASS_COMPLETE): logger_debug("recieved NEWPASS_COMPLETE event") t = KeyDist.genkeyThread(event.keydist) t.setDaemon(True) t.start() event.keydist.threads.append(t) event.Skip()
def run(self): sshKeyListCmd = self.keydistObject.sshpaths.sshAddBinary + " -L " keylist = subprocess.Popen(sshKeyListCmd, stdout = subprocess.PIPE,stderr=subprocess.STDOUT,shell=True,universal_newlines=True) (stdout,stderr) = keylist.communicate() self.keydistObject.pubkeylock.acquire() logger_debug('getPubKeyThread: stdout of ssh-add -l: ' + str(stdout)) logger_debug('getPubKeyThread: stderr of ssh-add -l: ' + str(stderr)) lines = stdout.split('\n') logger_debug("ssh key list completed") for line in lines: match = re.search("^(?P<keytype>\S+)\ (?P<key>\S+)\ (?P<keycomment>.+)$",line) if match: keycomment = match.group('keycomment') correctKey = re.search('.*{launchercomment}.*'.format(launchercomment=self.keydistObject.launcherKeyComment),keycomment) if correctKey: self.keydistObject.keyloaded = True logger_debug('getPubKeyThread: loaded key successfully') self.keydistObject.pubkey = line.rstrip() logger_debug("all lines processed") if (self.keydistObject.keyloaded): logger_debug("key loaded") logger_debug("getPubKeyThread found a key, posting TESTAUTH") newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_TESTAUTH,self.keydistObject) else: logger_debug("getPubKeyThread did not find a key, posting LOADKEY") newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_LOADKEY,self.keydistObject) self.keydistObject.pubkeylock.release() if (not self.stopped()): logger_debug("getPubKeyThread is posting the next event") wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(),newevent)
def cancel(self,message=""): if (not self.canceled()): self._canceled.set() newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_CANCEL, self) logger_debug('Sending EVT_KEYDIST_CANCEL event.') wx.PostEvent(self.notifywindow.GetEventHandler(), newevent)
def run(self): logger_debug("executing genkeyThread, run method") cmd = '{sshkeygen} -q -f "{keyfilename}" -C "{keycomment}" -N \"{password}\"'.format(sshkeygen=self.keydistObject.sshpaths.sshKeyGenBinary, keyfilename=self.keydistObject.sshpaths.sshKeyPath, keycomment=self.keydistObject.launcherKeyComment, password=self.keydistObject.password) try: keygen_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True) (stdout,stderr) = keygen_proc.communicate("\n\n") logger_debug("sshkeygen completed") if (stderr != None): logger_debug("key gen proc returned an error %s"%stderr) self.keydistObject.cancel("Unable to generate a new ssh key pair %s"%stderr) return if (stdout != None): logger_error("key gen proc returned a message %s"%stdout) #self.keydistObject.cancel("Unable to generate a new ssh key pair %s"%stderr) #return except Exception as e: logger_debug("sshkeygen threw and exception %s" % str(e)) self.keydistObject.cancel("Unable to generate a new ssh key pair: %s" % str(e)) return try: logger_debug("sshkeygen completed, trying to open the key file") with open(self.keydistObject.sshpaths.sshKeyPath,'r'): pass event = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_LOADKEY,self.keydistObject) # Auth hasn't really failed but this event will trigger loading the key except Exception as e: logger_error("ssh key gen failed %s" % str(e)) self.keydistObject.cancel("Unable to generate a new ssh key pair %s" % str(e)) return if (not self.stopped()): logger_debug("generating LOADKEY event from genkeyThread") wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(),event)
def run(self): # I have a problem where I have multiple identity files in my ~/.ssh, and I want to use only identities loaded into the agent # since openssh does not seem to have an option to use only an agent we have a workaround, # by passing the -o IdentityFile option a path that does not exist, openssh can't use any other identities, and can only use the agent. # This is a little "racy" in that a tempfile with the same path could concievably be created between the unlink and openssh attempting to use it # but since the pub key is extracted from the agent not the identity file I can't see anyway an attacker could use this to trick a user into uploading the attackers key. logger_debug("testAuthThread started") import tempfile, os (fd,path)=tempfile.mkstemp() os.close(fd) os.unlink(path) ssh_cmd = '{sshbinary} -o IdentityFile={nonexistantpath} -o PasswordAuthentication=no -o PubkeyAuthentication=yes -o StrictHostKeyChecking=yes -l {login} {host} echo "success_testauth"'.format(sshbinary=self.keydistObject.sshpaths.sshBinary, login=self.keydistObject.username, host=self.keydistObject.host, nonexistantpath=path) logger_debug('testAuthThread: attempting: ' + ssh_cmd) ssh = subprocess.Popen(ssh_cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True,universal_newlines=True) stdout, stderr = ssh.communicate() ssh.wait() logger_debug('testAuthThread: stdout of ssh command: ' + str(stdout)) logger_debug('testAuthThread: stderr of ssh command: ' + str(stderr)) if 'success_testauth' in stdout: logger_debug('testAuthThread: got success_testauth in stdout :)') self.keydistObject.authentication_success = True newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_AUTHSUCCESS,self.keydistObject) else: logger_debug('testAuthThread: did not see success_testauth in stdout, posting EVT_KEYDIST_AUTHFAIL event') newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_AUTHFAIL,self.keydistObject) if (not self.stopped()): logger_debug('testAuthThread: self.stopped() == False, so posting event: ' + str(newevent)) wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(),newevent)
def loadKey(self): try: f = open(self.keydistObject.sshpaths.sshKeyPath,'r') f.close() except IOError as e: # The key file didn't exist, so we should generate a new one. newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_NEWPASS_REQ,self.keydistObject) wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(),newevent) return if (self.keydistObject.password != None and len(self.keydistObject.password) > 0): passphrase = self.keydistObject.password else: passphrase = '' if sys.platform.startswith('win'): # The patched OpenSSH binary on Windows/cygwin allows us # to send the password via stdin. cmd = self.keydistObject.sshpaths.sshAddBinary + ' ' + double_quote(self.keydistObject.sshpaths.sshKeyPath) logger_debug('on Windows, so running: ' + cmd) stdout, stderr = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True).communicate(input=passphrase + '\r\n') if stdout is None or str(stdout).strip() == '': logger_debug('Got EOF from ssh-add binary') newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) elif 'Identity added' in stdout: logger_debug('Got "Identity added" from ssh-add binary') newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_GETPUBKEY, self.keydistObject) elif 'Bad pass' in stdout: logger_debug('Got "Bad pass" from ssh-add binary') if passphrase == '': newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) else: newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_WRONGPASS, self.keydistObject) else: logger_debug('Got unknown error from ssh-add binary') newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_LOCKED,self.keydistObject) else: # On Linux or BSD/OSX we can use pexpect to talk to ssh-add. args = [self.keydistObject.sshpaths.sshKeyPath] lp = pexpect.spawn(self.keydistObject.sshpaths.sshAddBinary, args=args) idx = lp.expect(["Identity added", ".*pass.*"]) if idx == 1: logger_debug("sending passphrase to ssh-add") lp.sendline(passphrase) idx = lp.expect(["Identity added", "Bad pass", pexpect.EOF]) if idx == 0: newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_GETPUBKEY, self.keydistObject) elif idx == 1: if passphrase == '': logger_debug("passphrase is an empty string ssh-add returned Bad pass") newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) else: newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_WRONGPASS, self.keydistObject) else: logger_debug("1 returning KEY_LOCKED %s %s"%(lp.before,lp.after)) newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) lp.close() if (not self.stopped()): wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), newevent)
def run(self): logger_debug("executing genkeyThread, run method") cmd = '{sshkeygen} -q -f "{keyfilename}" -C "{keycomment}" -N \"{password}\"'.format( sshkeygen=self.keydistObject.sshpaths.sshKeyGenBinary, keyfilename=self.keydistObject.sshpaths.sshKeyPath, keycomment=self.keydistObject.launcherKeyComment, password=self.keydistObject.password) try: keygen_proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True) (stdout, stderr) = keygen_proc.communicate("\n\n") logger_debug("sshkeygen completed") if (stderr != None): logger_debug("key gen proc returned an error %s" % stderr) self.keydistObject.cancel( "Unable to generate a new ssh key pair %s" % stderr) return if (stdout != None): logger_error("key gen proc returned a message %s" % stdout) #self.keydistObject.cancel("Unable to generate a new ssh key pair %s"%stderr) #return except Exception as e: logger_debug("sshkeygen threw and exception %s" % str(e)) self.keydistObject.cancel( "Unable to generate a new ssh key pair: %s" % str(e)) return try: logger_debug( "sshkeygen completed, trying to open the key file") with open(self.keydistObject.sshpaths.sshKeyPath, 'r'): pass event = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_LOADKEY, self.keydistObject ) # Auth hasn't really failed but this event will trigger loading the key except Exception as e: logger_error("ssh key gen failed %s" % str(e)) self.keydistObject.cancel( "Unable to generate a new ssh key pair %s" % str(e)) return if (not self.stopped()): logger_debug("generating LOADKEY event from genkeyThread") wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), event)
def loadKey(self): try: f = open(self.keydistObject.sshpaths.sshKeyPath, 'r') f.close() except IOError as e: # The key file didn't exist, so we should generate a new one. newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_NEWPASS_REQ, self.keydistObject) wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), newevent) return if (self.keydistObject.password != None and len(self.keydistObject.password) > 0): passphrase = self.keydistObject.password else: passphrase = '' if sys.platform.startswith('win'): # The patched OpenSSH binary on Windows/cygwin allows us # to send the password via stdin. cmd = self.keydistObject.sshpaths.sshAddBinary + ' ' + double_quote( self.keydistObject.sshpaths.sshKeyPath) logger_debug('on Windows, so running: ' + cmd) stdout, stderr = subprocess.Popen( cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True).communicate(input=passphrase + '\r\n') if stdout is None or str(stdout).strip() == '': logger_debug('Got EOF from ssh-add binary') newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) elif 'Identity added' in stdout: logger_debug('Got "Identity added" from ssh-add binary') newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_GETPUBKEY, self.keydistObject) elif 'Bad pass' in stdout: logger_debug('Got "Bad pass" from ssh-add binary') if passphrase == '': newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) else: newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_WRONGPASS, self.keydistObject) else: logger_debug('Got unknown error from ssh-add binary') newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) else: # On Linux or BSD/OSX we can use pexpect to talk to ssh-add. args = [self.keydistObject.sshpaths.sshKeyPath] lp = pexpect.spawn(self.keydistObject.sshpaths.sshAddBinary, args=args) idx = lp.expect(["Identity added", ".*pass.*"]) if idx == 1: logger_debug("sending passphrase to ssh-add") lp.sendline(passphrase) idx = lp.expect( ["Identity added", "Bad pass", pexpect.EOF]) if idx == 0: newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_GETPUBKEY, self.keydistObject) elif idx == 1: if passphrase == '': logger_debug( "passphrase is an empty string ssh-add returned Bad pass" ) newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) else: newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_WRONGPASS, self.keydistObject) else: logger_debug("1 returning KEY_LOCKED %s %s" % (lp.before, lp.after)) newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_KEY_LOCKED, self.keydistObject) lp.close() if (not self.stopped()): wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), newevent)
def run(self): # I have a problem where I have multiple identity files in my ~/.ssh, and I want to use only identities loaded into the agent # since openssh does not seem to have an option to use only an agent we have a workaround, # by passing the -o IdentityFile option a path that does not exist, openssh can't use any other identities, and can only use the agent. # This is a little "racy" in that a tempfile with the same path could concievably be created between the unlink and openssh attempting to use it # but since the pub key is extracted from the agent not the identity file I can't see anyway an attacker could use this to trick a user into uploading the attackers key. logger_debug("testAuthThread started") import tempfile, os (fd, path) = tempfile.mkstemp() os.close(fd) os.unlink(path) ssh_cmd = '{sshbinary} -o IdentityFile={nonexistantpath} -o PasswordAuthentication=no -o PubkeyAuthentication=yes -o StrictHostKeyChecking=yes -l {login} {host} echo "success_testauth"'.format( sshbinary=self.keydistObject.sshpaths.sshBinary, login=self.keydistObject.username, host=self.keydistObject.host, nonexistantpath=path) logger_debug('testAuthThread: attempting: ' + ssh_cmd) ssh = subprocess.Popen(ssh_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True) stdout, stderr = ssh.communicate() ssh.wait() logger_debug('testAuthThread: stdout of ssh command: ' + str(stdout)) logger_debug('testAuthThread: stderr of ssh command: ' + str(stderr)) if 'success_testauth' in stdout: logger_debug( 'testAuthThread: got success_testauth in stdout :)') self.keydistObject.authentication_success = True newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_AUTHSUCCESS, self.keydistObject) else: logger_debug( 'testAuthThread: did not see success_testauth in stdout, posting EVT_KEYDIST_AUTHFAIL event' ) newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_AUTHFAIL, self.keydistObject) if (not self.stopped()): logger_debug( 'testAuthThread: self.stopped() == False, so posting event: ' + str(newevent)) wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), newevent)
def run(self): sshKeyListCmd = self.keydistObject.sshpaths.sshAddBinary + " -L " keylist = subprocess.Popen(sshKeyListCmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True) (stdout, stderr) = keylist.communicate() self.keydistObject.pubkeylock.acquire() logger_debug('getPubKeyThread: stdout of ssh-add -l: ' + str(stdout)) logger_debug('getPubKeyThread: stderr of ssh-add -l: ' + str(stderr)) lines = stdout.split('\n') logger_debug("ssh key list completed") for line in lines: match = re.search( "^(?P<keytype>\S+)\ (?P<key>\S+)\ (?P<keycomment>.+)$", line) if match: keycomment = match.group('keycomment') correctKey = re.search( '.*{launchercomment}.*'.format( launchercomment=self.keydistObject. launcherKeyComment), keycomment) if correctKey: self.keydistObject.keyloaded = True logger_debug( 'getPubKeyThread: loaded key successfully') self.keydistObject.pubkey = line.rstrip() logger_debug("all lines processed") if (self.keydistObject.keyloaded): logger_debug("key loaded") logger_debug("getPubKeyThread found a key, posting TESTAUTH") newevent = KeyDist.sshKeyDistEvent( KeyDist.EVT_KEYDIST_TESTAUTH, self.keydistObject) else: logger_debug( "getPubKeyThread did not find a key, posting LOADKEY") newevent = KeyDist.sshKeyDistEvent(KeyDist.EVT_KEYDIST_LOADKEY, self.keydistObject) self.keydistObject.pubkeylock.release() if (not self.stopped()): logger_debug("getPubKeyThread is posting the next event") wx.PostEvent(self.keydistObject.notifywindow.GetEventHandler(), newevent)