1# -*- test-case-name: twisted.conch.test.test_default -*- 2# Copyright (c) Twisted Matrix Laboratories. 3# See LICENSE for details. 4 5""" 6Accesses the key agent for user authentication. 7 8Maintainer: Paul Swartz 9""" 10 11import os 12 13from twisted.conch.ssh import agent, channel, keys 14from twisted.internet import protocol, reactor 15from twisted.python import log 16 17 18 19class SSHAgentClient(agent.SSHAgentClient): 20 21 def __init__(self): 22 agent.SSHAgentClient.__init__(self) 23 self.blobs = [] 24 25 26 def getPublicKeys(self): 27 return self.requestIdentities().addCallback(self._cbPublicKeys) 28 29 30 def _cbPublicKeys(self, blobcomm): 31 log.msg('got %i public keys' % len(blobcomm)) 32 self.blobs = [x[0] for x in blobcomm] 33 34 35 def getPublicKey(self): 36 """ 37 Return a L{Key} from the first blob in C{self.blobs}, if any, or 38 return C{None}. 39 """ 40 if self.blobs: 41 return keys.Key.fromString(self.blobs.pop(0)) 42 return None 43 44 45 46class SSHAgentForwardingChannel(channel.SSHChannel): 47 48 def channelOpen(self, specificData): 49 cc = protocol.ClientCreator(reactor, SSHAgentForwardingLocal) 50 d = cc.connectUNIX(os.environ['SSH_AUTH_SOCK']) 51 d.addCallback(self._cbGotLocal) 52 d.addErrback(lambda x:self.loseConnection()) 53 self.buf = '' 54 55 56 def _cbGotLocal(self, local): 57 self.local = local 58 self.dataReceived = self.local.transport.write 59 self.local.dataReceived = self.write 60 61 62 def dataReceived(self, data): 63 self.buf += data 64 65 66 def closed(self): 67 if self.local: 68 self.local.loseConnection() 69 self.local = None 70 71 72class SSHAgentForwardingLocal(protocol.Protocol): 73 pass 74