Exemple #1
0
 def request_env(self, data):
     name, rest = getNS(data)
     value, rest = getNS(rest)
     if rest:
         raise ValueError("Bad data given in env request")
     log.msg(eventid='KIPP0013', format='request_env: %(name)s=%(value)s', name=name, value=value)
     return 0
Exemple #2
0
 def auth_publickey(self, packet):
     # This is copied and pasted from twisted/conch/ssh/userauth.py in
     # Twisted 8.0.1. We do this so we can customize how the credentials
     # are built and pass a mind to self.portal.login.
     hasSig = ord(packet[0])
     algName, blob, rest = getNS(packet[1:], 2)
     pubKey = keys.Key.fromString(blob).keyObject
     signature = hasSig and getNS(rest)[0] or None
     if hasSig:
         b = (
             NS(self.transport.sessionID)
             + chr(userauth.MSG_USERAUTH_REQUEST)
             + NS(self.user)
             + NS(self.nextService)
             + NS("publickey")
             + chr(hasSig)
             + NS(keys.objectType(pubKey))
             + NS(blob)
         )
         # The next three lines are different from the original.
         c = self.makePublicKeyCredentials(self.user, algName, blob, b, signature)
         return self.portal.login(c, self.getMind(), IConchUser)
     else:
         # The next four lines are different from the original.
         c = self.makePublicKeyCredentials(self.user, algName, blob, None, None)
         return self.portal.login(c, self.getMind(), IConchUser).addErrback(self._ebCheckKey, packet[1:])
    def auth_publickey(self, packet):
        """
        Public key authentication.  Payload::
            byte has signature
            string algorithm name
            string key blob
            [string signature] (if has signature is True)

        Create a SSHPublicKey credential and verify it using our portal.
        """
        hasSig = ord(packet[0:1])
        algName, blob, rest = getNS(packet[1:], 2)

        try:
            pubKey = keys.Key.fromString(blob)
        except keys.BadKeyError:
            error = "Unsupported key type %s or bad key" % (
                algName.decode('ascii'),)
            log.msg(error)
            return defer.fail(UnauthorizedLogin(error))

        signature = hasSig and getNS(rest)[0] or None
        if hasSig:
            b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) +
                NS(self.user) + NS(self.nextService) + NS(b'publickey') +
                chr(hasSig) +  NS(pubKey.sshType()) + NS(blob))
            c = credentials.SSHPrivateKey(self.user, algName, blob, b,
                    signature)
            return self.portal.login(c, None, interfaces.IConchUser)
        else:
            c = credentials.SSHPrivateKey(self.user, algName, blob, None, None)
            return self.portal.login(c, None,
                    interfaces.IConchUser).addErrback(self._ebCheckKey,
                            packet[1:])
 def _parseAttributes(self, data):
     flags ,= struct.unpack('!L', data[:4])
     attrs = {}
     data = data[4:]
     if flags & FILEXFER_ATTR_SIZE == FILEXFER_ATTR_SIZE:
         size ,= struct.unpack('!Q', data[:8])
         attrs['size'] = size
         data = data[8:]
     if flags & FILEXFER_ATTR_OWNERGROUP == FILEXFER_ATTR_OWNERGROUP:
         uid, gid = struct.unpack('!2L', data[:8])
         attrs['uid'] = uid
         attrs['gid'] = gid
         data = data[8:]
     if flags & FILEXFER_ATTR_PERMISSIONS == FILEXFER_ATTR_PERMISSIONS:
         perms ,= struct.unpack('!L', data[:4])
         attrs['permissions'] = perms
         data = data[4:]
     if flags & FILEXFER_ATTR_ACMODTIME == FILEXFER_ATTR_ACMODTIME:
         atime, mtime = struct.unpack('!2L', data[:8])
         attrs['atime'] = atime
         attrs['mtime'] = mtime
         data = data[8:]
     if flags & FILEXFER_ATTR_EXTENDED == FILEXFER_ATTR_EXTENDED:
         extended_count ,= struct.unpack('!L', data[:4])
         data = data[4:]
         for i in xrange(extended_count):
             extended_type, data = getNS(data)
             extended_data, data = getNS(data)
             attrs['ext_%s' % extended_type] = extended_data
     return attrs, data
Exemple #5
0
 def ssh_USERAUTH_PK_OK(self, packet):
     if self.lastAuth == 'publickey':
         # this is ok
         publicKey = self.lastPublicKey
         keyType =  getNS(publicKey)[0]
         b = NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) + \
         NS(self.user) + NS(self.instance.name) + NS('publickey') + '\xff' +\
         NS(keyType) + NS(publicKey)
         d  = self.signData(publicKey, b)
         if not d:
             self.askForAuth('none', '')
             # this will fail, we'll move on
             return
         d.addCallback(self._cbSignedData)
         d.addErrback(self._ebAuth)
     elif self.lastAuth == 'password':
         prompt, language, rest = getNS(packet, 2)
         self._oldPass = self._newPass = None
         self.getPassword('Old Password: '******'keyboard-interactive':
         name, instruction, lang, data = getNS(packet, 3)
         numPrompts = struct.unpack('!L', data[:4])[0]
         data = data[4:]
         prompts = []
         for i in range(numPrompts):
             prompt, data = getNS(data)
             echo = bool(ord(data[0]))
             data = data[1:]
             prompts.append((prompt, echo))
         d = self.getGenericAnswers(name, instruction, prompts)
         d.addCallback(self._cbGenericAnswers)
         d.addErrback(self._ebAuth)
Exemple #6
0
    def verify(self, signature, data):
        """
        Returns true if the signature for data is valid for this Key.

        @type signature: C{str}
        @type data: C{str}
        @rtype: C{bool}
        """
        if len(signature) == 40:
            # DSA key with no padding
            signatureType, signature = 'ssh-dss', common.NS(signature)
        else:
            signatureType, signature = common.getNS(signature)
        if signatureType != self.sshType():
            return False
        if self.type() == 'RSA':
            numbers = common.getMP(signature)
            digest = pkcs1Digest(data, self.keyObject.size() / 8)
        elif self.type() == 'DSA':
            signature = common.getNS(signature)[0]
            numbers = [
                Util.number.bytes_to_long(n) for n in
                    (signature[:20], signature[20:])
                ]
            digest = sha1(data).digest()
        return self.keyObject.verify(digest, numbers)
Exemple #7
0
    def auth_publickey(self, packet):
        """
        Public key authentication.  Payload::
            byte has signature
            string algorithm name
            string key blob
            [string signature] (if has signature is True)

        Create a SSHPublicKey credential and verify it using our portal.
        """
        hasSig = ord(packet[0])
        algName, blob, rest = getNS(packet[1:], 2)
        pubKey = keys.Key.fromString(blob)
        signature = hasSig and getNS(rest)[0] or None
        if hasSig:
            b = (NS(self.transport.sessionID) + chr(MSG_USERAUTH_REQUEST) +
                NS(self.user) + NS(self.nextService) + NS('publickey') +
                chr(hasSig) +  NS(pubKey.sshType()) + NS(blob))
            c = credentials.SSHPrivateKey(self.user, algName, blob, b,
                    signature)
            return self.portal.login(c, None, interfaces.IConchUser)
        else:
            c = credentials.SSHPrivateKey(self.user, algName, blob, None, None)
            return self.portal.login(c, None,
                    interfaces.IConchUser).addErrback(self._ebCheckKey,
                            packet[1:])
Exemple #8
0
    def request_env(self, data):
	name, rest = getNS(data)
	value, rest = getNS(rest)
	if rest:
	    raise ValueError("Bad data given in env request")
	log.msg('request_env: %s=%s' % (name, value) )
	return 0
Exemple #9
0
    def auth_publickey(self, packet):

        try:
            #extract the public key blob from the SSH packet
            key_blob = getNS(getNS(packet[1:])[1])[0]
        except:
            key_blob = "No public key found."

        try:
            #convert blob into openssh key format
            key = keys.Key.fromString(key_blob).toString('openssh')
        except:
            key = "Invalid SSH Public Key Submitted: {key_blob}".format(key_blob=key_blob.encode('hex'))
            for keytype in ['ecdsa-sha2-nistp256','ecdsa-sha2-nistp384','ecdsa-sha2-nistp521','ssh-ed25519']:
                if keytype in key_blob:
                    key = '{keytype} {keydata}'.format(
                            keytype=keytype,
                            keydata=base64.b64encode(key_blob))

            print 'Key was {key}'.format(key=key)

        c = credentials.SSHPrivateKey(None,None,None,None,None)

        #self.log(key=key)

        return self.portal.login(c, None, conchinterfaces.IConchUser).addErrback(
                                                        self._ebPassword)
 def packet_SYMLINK(self, data):
     requestId = data[:4]
     data = data[4:]
     linkPath, data = getNS(data)
     targetPath, data = getNS(data)
     d = defer.maybeDeferred(self.client.makeLink, linkPath, targetPath)
     d.addCallback(self._cbStatus, requestId, 'symlink succeeded')
     d.addErrback(self._ebStatus, requestId, 'symlink failed')
def unpackOpen_direct_tcpip(data):
    """Unpack the data to a usable format.
    """
    connHost, rest = common.getNS(data)
    connPort = int(struct.unpack('>L', rest[:4])[0])
    origHost, rest = common.getNS(rest[4:])
    origPort = int(struct.unpack('>L', rest[:4])[0])
    return (connHost, connPort), (origHost, origPort)
 def packet_RENAME(self, data):
     requestId = data[:4]
     data = data[4:]
     oldPath, data = getNS(data)
     newPath, data = getNS(data)
     assert data == '', 'still have data in RENAME: %s' % repr(data)
     d = defer.maybeDeferred(self.client.renameFile, oldPath, newPath)
     d.addCallback(self._cbStatus, requestId, "rename succeeded")
     d.addErrback(self._ebStatus, requestId, "rename failed")
 def packet_HANDLE(self, data):
     d, data = self._parseRequest(data)
     isFile, name = self.wasAFile.pop(d)
     if isFile:
         cb = ClientFile(self, getNS(data)[0])
     else:
         cb = ClientDirectory(self, getNS(data)[0])
     cb.name = name
     d.callback(cb)
Exemple #14
0
 def request_env(self, data):
     name, rest = getNS(data)
     value, rest = getNS(rest)
     if rest:
         raise ValueError("Bad data given in env request")
     log.msg(eventid='cowrie.client.var', format='request_env: %(name)s=%(value)s', name=name, value=value)
     # FIXME: This only works for shell, not for exec command
     # if self.session:
     #     self.session.environ[name] = value
     return 0
 def packet_VERSION(self, data):
     version, = struct.unpack('!L', data[:4])
     data = data[4:]
     d = {}
     while data:
         k, data = getNS(data)
         v, data = getNS(data)
         d[k]=v
     self.version = version
     self.gotServerVersion(version, d)
Exemple #16
0
def parseRequest_pty_req(data):
    """Parse the data from a pty-req request into usable data.

    @returns: a tuple of (terminal type, (rows, cols, xpixel, ypixel), modes)
    """
    term, rest = common.getNS(data)
    cols, rows, xpixel, ypixel = struct.unpack('>4L', rest[: 16])
    modes, ignored= common.getNS(rest[16:])
    winSize = (rows, cols, xpixel, ypixel)
    modes = [(ord(modes[i]), struct.unpack('>L', modes[i+1: i+5])[0]) for i in range(0, len(modes)-1, 5)]
    return term, winSize, modes
 def packet_NAME(self, data):
     d, data = self._parseRequest(data)
     count, = struct.unpack('!L', data[:4])
     data = data[4:]
     files = []
     for i in range(count):
         filename, data = getNS(data)
         longname, data = getNS(data)
         attrs, data = self._parseAttributes(data)
         files.append((filename, longname, attrs))
     d.callback(files)
def unpackOpen_direct_tcpip(data):
    """Unpack the data to a usable format.
    """
    connHost, rest = common.getNS(data)
    if _PY3 and isinstance(connHost, bytes):
        connHost = connHost.decode("utf-8")
    connPort = int(struct.unpack('>L', rest[:4])[0])
    origHost, rest = common.getNS(rest[4:])
    if _PY3 and isinstance(origHost, bytes):
        origHost = origHost.decode("utf-8")
    origPort = int(struct.unpack('>L', rest[:4])[0])
    return (connHost, connPort), (origHost, origPort)
Exemple #19
0
 def agentc_SIGN_REQUEST(self, data):
     """
     Data is a structure with a reference to an already added key object and
     some data that the clients wants signed with that key.  If the key
     object wasn't loaded, return AGENT_FAILURE, else return the signature.
     """
     blob, data = getNS(data)
     if blob not in self.factory.keys:
         return self.sendResponse(AGENT_FAILURE, '')
     signData, data = getNS(data)
     assert data == '\000\000\000\000'
     self.sendResponse(AGENT_SIGN_RESPONSE, NS(self.factory.keys[blob][0].sign(signData)))
Exemple #20
0
 def request_env(self, data):
     """
     """
     name, rest = getNS(data)
     value, rest = getNS(rest)
     if rest:
         raise ValueError("Bad data given in env request")
     log.msg(eventid='KIPP0013', format='request_env: %(name)s=%(value)s',
         name=name, value=value)
     # Environment variables come after shell or before exec command
     if self.session:
         self.session.environ[name] = value
     return 0
Exemple #21
0
    def verify(self, signature, data):
        """
        Verify a signature using this key.

        @type signature: L{bytes}
        @param signature: The signature to verify.

        @type data: L{bytes}
        @param data: The signed data.

        @rtype: L{bool}
        @return: C{True} if the signature is valid.
        """
        if len(signature) == 40:
            # DSA key with no padding
            signatureType, signature = b'ssh-dss', common.NS(signature)
        else:
            signatureType, signature = common.getNS(signature)
        if signatureType != self.sshType():
            return False
        if self.type() == 'RSA':
            k = self._keyObject
            if not self.isPublic():
                k = k.public_key()
            verifier = k.verifier(
                common.getNS(signature)[0],
                padding.PKCS1v15(),
                hashes.SHA1(),
            )
        elif self.type() == 'DSA':
            concatenatedSignature = common.getNS(signature)[0]
            r = int_from_bytes(concatenatedSignature[:20], 'big')
            s = int_from_bytes(concatenatedSignature[20:], 'big')
            signature = encode_dss_signature(r, s)
            k = self._keyObject
            if not self.isPublic():
                k = k.public_key()
            verifier = k.verifier(
                signature, hashes.SHA1())
        else:
            raise BadKeyError("unknown key type %s" % (self.type(),))

        verifier.update(data)
        try:
            verifier.verify()
        except InvalidSignature:
            return False
        else:
            return True
 def packet_INIT(self, data):
     version ,= struct.unpack('!L', data[:4])
     self.version = min(list(self.versions) + [version])
     data = data[4:]
     ext = {}
     while data:
         ext_name, data = getNS(data)
         ext_data, data = getNS(data)
         ext[ext_name] = ext_data
     our_ext = self.client.gotVersion(version, ext)
     our_ext_data = ""
     for (k,v) in our_ext.items():
         our_ext_data += NS(k) + NS(v)
     self.sendPacket(FXP_VERSION, struct.pack('!L', self.version) + \
                                  our_ext_data)
 def packet_WRITE(self, data):
     requestId = data[:4]
     data = data[4:]
     handle, data = getNS(data)
     offset, = struct.unpack('!Q', data[:8])
     data = data[8:]
     writeData, data = getNS(data)
     assert data == '', 'still have data in WRITE: %s' % repr(data)
     if handle not in self.openFiles:
         self._ebWrite(failure.Failure(KeyError()), requestId)
     else:
         fileObj = self.openFiles[handle]
         d = defer.maybeDeferred(fileObj.writeChunk, offset, writeData)
         d.addCallback(self._cbStatus, requestId, "write succeeded")
         d.addErrback(self._ebStatus, requestId, "write failed")
Exemple #24
0
 def _cbRequestIdentities(self, data):
     """
     Unpack a collection of identities into a list of tuples comprised of
     public key blobs and comments.
     """
     if ord(data[0]) != AGENT_IDENTITIES_ANSWER:
         raise ConchError('unexpected response: %i' % ord(data[0]))
     numKeys = struct.unpack('!L', data[1:5])[0]
     keys = []
     data = data[5:]
     for i in range(numKeys):
         blob, data = getNS(data)
         comment, data = getNS(data)
         keys.append((blob, comment))
     return keys
Exemple #25
0
    def ssh_USERAUTH_REQUEST(self, packet):
        """
        The client has requested authentication.  Payload::
            string user
            string next service
            string method
            <authentication specific data>

        @type packet: C{str}
        """
        user, nextService, method, rest = getNS(packet, 3)
        if user != self.user or nextService != self.nextService:
            self.authenticatedWith = [] # clear auth state
        self.user = user
        self.nextService = nextService
        self.method = method
        d = self.tryAuth(method, user, rest)
        if not d:
            self._ebBadAuth(
                failure.Failure(error.ConchError('auth returned none')))
            return
        d.addCallback(self._cbFinishedAuth)
        d.addErrback(self._ebMaybeBadAuth)
        d.addErrback(self._ebBadAuth)
        return d
Exemple #26
0
 def isInKnownHosts(self, host, pubKey):
     """checks to see if host is in the known_hosts file for the user.
     returns 0 if it isn't, 1 if it is and is the same, 2 if it's changed.
     """
     keyType = common.getNS(pubKey)[0]
     retVal = 0
     try:
         known_hosts = open(os.path.expanduser('~/.ssh/known_hosts'))
     except IOError:
         return 0
     for line in known_hosts.xreadlines():
         split = line.split()
         if len(split) != 3: # old 4-field known_hosts entry (ssh1?)
             continue
         hosts, hostKeyType, encodedKey = split
         if not host in hosts.split(','): # incorrect host
             continue
         if not hostKeyType == keyType: # incorrect type of key
             continue
         try:
             decodedKey = base64.decodestring(encodedKey)
         except:
             continue
         if decodedKey == pubKey:
             return 1
         else:
             retVal = 2
     return retVal
Exemple #27
0
    def ssh_USERAUTH_INFO_RESPONSE(self, packet):
        """
        The user has responded with answers to PAMs authentication questions.
        Parse the packet into a PAM response and callback self._pamDeferred.
        Payload::
            uint32 numer of responses
            string response 1
            ...
            string response n
        """
        d, self._pamDeferred = self._pamDeferred, None

        try:
            resp = []
            numResps = struct.unpack('>L', packet[:4])[0]
            packet = packet[4:]
            while len(resp) < numResps:
                response, packet = getNS(packet)
                resp.append((response, 0))
            if packet:
                raise error.ConchError("%i bytes of extra data" % len(packet))
        except:
            d.errback(failure.Failure())
        else:
            d.callback(resp)
Exemple #28
0
    def verifyHostKey(self, pubKey, fingerprint):
        goodKey = self.isInKnownHosts(options['host'], pubKey)
        if goodKey == 1: # good key
            return defer.succeed(1)
        elif goodKey == 2: # AAHHHHH changed
            return defer.fail(ConchError('changed host key'))
        else:
            oldout, oldin = sys.stdout, sys.stdin
            sys.stdin = sys.stdout = open('/dev/tty','r+')
            if options['host'] == self.transport.getPeer()[1]:
                host = options['host']
                khHost = options['host']
            else:
                host = '%s (%s)' % (options['host'],
                                    self.transport.getPeer()[1])
                khHost = '%s,%s' % (options['host'],
                                    self.transport.getPeer()[1])
            keyType = common.getNS(pubKey)[0]
            print """The authenticity of host '%s' can't be extablished.
%s key fingerprint is %s.""" % (host,
                                {'ssh-dss':'DSA', 'ssh-rsa':'RSA'}[keyType],
                                fingerprint)
            ans = raw_input('Are you sure you want to continue connecting (yes/no)? ')
            while ans.lower() not in ('yes', 'no'):
                ans = raw_input("Please type 'yes' or 'no': ")
            sys.stdout,sys.stdin=oldout,oldin
            if ans == 'no':
                print 'Host key verification failed.'
                return defer.fail(ConchError('bad host key'))
            print "Warning: Permanently added '%s' (%s) to the list of known hosts." % (khHost, {'ssh-dss':'DSA', 'ssh-rsa':'RSA'}[keyType])
            known_hosts = open(os.path.expanduser('~/.ssh/known_hosts'), 'a')
            encodedKey = base64.encodestring(pubKey).replace('\n', '')
            known_hosts.write('\n%s %s %s' % (khHost, keyType, encodedKey))
            known_hosts.close()
            return defer.succeed(1)
    def ssh_CHANNEL_EXTENDED_DATA(self, packet):
        """
        The other side is sending us exteneded data.  Payload::
            uint32  local channel number
            uint32  type code
            string  data

        Check to make sure the other side hasn't sent too much data (more
        than what's in the window, or or than the maximum packet size).  If
        they have, close the channel.  Otherwise, decrease the available
        window and pass the data and type code to the channel's
        extReceived().
        """
        localChannel, typeCode, dataLength = struct.unpack('>3L', packet[:12])
        channel = self.channels[localChannel]
        if (dataLength > channel.localWindowLeft or
                dataLength > channel.localMaxPacket):
            log.callWithLogger(channel, log.msg, 'too much extdata')
            self.sendClose(channel)
            return
        data = common.getNS(packet[8:])[0]
        channel.localWindowLeft -= dataLength
        if channel.localWindowLeft < channel.localWindowSize / 2:
            self.adjustWindow(channel, channel.localWindowSize -
                                       channel.localWindowLeft)
        log.callWithLogger(channel, channel.extReceived, typeCode, data)
 def packet_EXTENDED(self, data):
     requestId = data[:4]
     data = data[4:]
     extName, extData = getNS(data)
     d = defer.maybeDeferred(self.client.extendedRequest, extName, extData)
     d.addCallback(self._cbExtended, requestId)
     d.addErrback(self._ebStatus, requestId, 'extended %s failed' % extName)
Exemple #31
0
    def ssh_KEXINIT(self, packet):
        k = getNS(packet[16:], 10)
        strings, rest = k[:-1], k[-1]
        (kexAlgs, keyAlgs, encCS, encSC, macCS, macSC, compCS, compSC, langCS,
         langSC) = [s.split(',') for s in strings]
        log.msg('KEXINIT: client supported key exchange: %s' % kexAlgs)
        log.msg('KEXINIT: client supported public keys: %s' % keyAlgs)
        log.msg('KEXINIT: client supported encryption: %s' % encCS)
        log.msg('KEXINIT: client supported MAC: %s' % macCS)
        log.msg('KEXINIT: client supported compression: %s' % compCS)
        log.msg('KEXINIT: client supported lang: %s' % langCS)

        log.msg(eventid='KIPP0009',
                version=self.otherVersionString,
                kexAlgs=kexAlgs,
                keyAlgs=keyAlgs,
                encCS=encCS,
                macCS=macCS,
                compCS=compCS,
                format='Remote SSH version: %(version)s')

        return sshserver.CowrieSSHServerTransport.ssh_KEXINIT(self, packet)
Exemple #32
0
    def _fromString_PRIVATE_BLOB(cls, blob):
        """
        Return a private key object corresponding to this private key blob.
        The blob formats are as follows:

        RSA keys::
            string 'ssh-rsa'
            integer n
            integer e
            integer d
            integer u
            integer p
            integer q

        DSA keys::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y
            integer x

        @type blob: L{bytes}
        @param blob: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the key type (the first string) is unknown.
        """
        keyType, rest = common.getNS(blob)

        if keyType == b'ssh-rsa':
            n, e, d, u, p, q, rest = common.getMP(rest, 6)
            return cls._fromRSAComponents(n=n, e=e, d=d, p=p, q=q)
        elif keyType == b'ssh-dss':
            p, q, g, y, x, rest = common.getMP(rest, 5)
            return cls._fromDSAComponents(y=y, g=g, p=p, q=q, x=x)
        else:
            raise BadKeyError('unknown blob type: %s' % (keyType, ))
Exemple #33
0
    def ssh_CHANNEL_REQUEST(self, packet):
        """
        The other side is sending a request to a channel.  Payload::
            uint32  local channel number
            string  request name
            bool    want reply
            <request specific data>

        Pass the message to the channel's requestReceived method.  If the
        other side wants a reply, add callbacks which will send the
        reply.
        """
        localChannel = struct.unpack('>L', packet[:4])[0]
        requestType, rest = common.getNS(packet[4:])
        wantReply = ord(rest[0:1])
        channel = self.channels[localChannel]
        d = defer.maybeDeferred(log.callWithLogger, channel,
                                channel.requestReceived, requestType, rest[1:])
        if wantReply:
            d.addCallback(self._cbChannelRequest, localChannel)
            d.addErrback(self._ebChannelRequest, localChannel)
            return d
Exemple #34
0
    def _fromString_PRIVATE_BLOB(Class, blob):
        """
        Return a private key object corresponding to this private key blob.
        The blob formats are as follows:

        RSA keys::
            string 'ssh-rsa'
            integer n
            integer e
            integer d
            integer u
            integer p
            integer q

        DSA keys::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y
            integer x

        @type blob: C{str}
        @return: a C{Crypto.PublicKey.pubkey.pubkey} object
        @raises BadKeyError: if the key type (the first string) is unknown.
        """
        keyType, rest = common.getNS(blob)

        if keyType == 'ssh-rsa':
            n, e, d, u, p, q, rest = common.getMP(rest, 6)
            rsakey = Class(RSA.construct((n, e, d, p, q, u)))
            return rsakey
        elif keyType == 'ssh-dss':
            p, q, g, y, x, rest = common.getMP(rest, 5)
            dsakey = Class(DSA.construct((y, g, p, q, x)))
            return dsakey
        else:
            raise BadKeyError('unknown blob type: %s' % keyType)
Exemple #35
0
def isInKnownHosts(host, pubKey, options):
    """
    Checks to see if host is in the known_hosts file for the user.

    @return: 0 if it isn't, 1 if it is and is the same, 2 if it's changed.
    @rtype: L{int}
    """
    keyType = common.getNS(pubKey)[0]
    retVal = 0

    if not options['known-hosts'] and not os.path.exists(
            os.path.expanduser('~/.ssh/')):
        print('Creating ~/.ssh directory...')
        os.mkdir(os.path.expanduser('~/.ssh'))
    kh_file = options['known-hosts'] or _KNOWN_HOSTS
    try:
        known_hosts = open(os.path.expanduser(kh_file), 'rb')
    except IOError:
        return 0
    with known_hosts:
        for line in known_hosts.readlines():
            split = line.split()
            if len(split) < 3:
                continue
            hosts, hostKeyType, encodedKey = split[:3]
            if host not in hosts.split(b','):  # incorrect host
                continue
            if hostKeyType != keyType:  # incorrect type of key
                continue
            try:
                decodedKey = decodebytes(encodedKey)
            except:
                continue
            if decodedKey == pubKey:
                return 1
            else:
                retVal = 2
    return retVal
Exemple #36
0
    def ssh_KEXINIT(self, packet):
        """
        """
        cookie = packet[:16]
        log.msg("EXPERIMENTAL KEXINIT cookie %s" % (cookie.encode('hex'), ))
        k = getNS(packet[16:], 10)
        strings, rest = k[:-1], k[-1]
        (kexAlgs, keyAlgs, encCS, encSC, macCS, macSC, compCS, compSC, langCS,
         langSC) = [s.split(',') for s in strings]
        log.msg("EXPERIMENTAL KEXINIT langCS langSC %s %s" % (
            langCS,
            langSC,
        ))
        log.msg(eventid='COW0009',
                version=self.otherVersionString,
                kexAlgs=kexAlgs,
                keyAlgs=keyAlgs,
                encCS=encCS,
                macCS=macCS,
                compCS=compCS,
                format='Remote SSH version: %(version)s')

        return transport.SSHServerTransport.ssh_KEXINIT(self, packet)
Exemple #37
0
 def _guessStringType(Class, data):
     """
     Guess the type of key in data.  The types map to _fromString_*
     methods.
     """
     if data.startswith('ssh-'):
         return 'public_openssh'
     elif data.startswith('-----BEGIN'):
         return 'private_openssh'
     elif data.startswith('{'):
         return 'public_lsh'
     elif data.startswith('('):
         return 'private_lsh'
     elif data.startswith('\x00\x00\x00\x07ssh-'):
         ignored, rest = common.getNS(data)
         count = 0
         while rest:
             count += 1
             ignored, rest = common.getMP(rest)
         if count > 4:
             return 'agentv3'
         else:
             return 'blob'
Exemple #38
0
    def _fromString_BLOB(cls, blob):
        """
        Return a public key object corresponding to this public key blob.
        The format of a RSA public key blob is::
            string 'ssh-rsa'
            integer e
            integer n

        The format of a DSA public key blob is::
            string 'ssh-dss'
            integer p
            integer q
            integer g
            integer y

        @type blob: L{bytes}
        @param blob: The key data.

        @return: A new key.
        @rtype: L{twisted.conch.ssh.keys.Key}
        @raises BadKeyError: if the key type (the first string) is unknown.
        """
        keyType, rest = common.getNS(blob)
        if keyType == b'ssh-rsa':
            e, n, rest = common.getMP(rest, 2)
            return cls(
                rsa.RSAPublicNumbers(e, n).public_key(default_backend()))
        elif keyType == b'ssh-dss':
            p, q, g, y, rest = common.getMP(rest, 4)
            return cls(
                dsa.DSAPublicNumbers(y=y,
                                     parameter_numbers=dsa.DSAParameterNumbers(
                                         p=p, q=q,
                                         g=g)).public_key(default_backend()))
        else:
            raise BadKeyError('unknown blob type: %s' % (keyType, ))
Exemple #39
0
    def ssh_USERAUTH_REQUEST(self, packet):
        """
        The client has requested authentication.  Payload::
            string user
            string next service
            string method
            <authentication specific data>

        @type packet: L{bytes}
        """
        user, nextService, method, rest = getNS(packet, 3)
        if user != self.user or nextService != self.nextService:
            self.authenticatedWith = []  # clear auth state
        self.user = user
        self.nextService = nextService
        self.method = method
        d = self.tryAuth(method, user, rest)
        if not d:
            self._ebBadAuth(failure.Failure(error.ConchError("auth returned none")))
            return
        d.addCallback(self._cbFinishedAuth)
        d.addErrback(self._ebMaybeBadAuth)
        d.addErrback(self._ebBadAuth)
        return d
Exemple #40
0
    def ssh_KEXINIT(self, packet):
        """
        Called when we receive a MSG_KEXINIT message.  Payload::
            bytes[16] cookie
            string keyExchangeAlgorithms
            string keyAlgorithms
            string incomingEncryptions
            string outgoingEncryptions
            string incomingAuthentications
            string outgoingAuthentications
            string incomingCompressions
            string outgoingCompressions
            string incomingLanguages
            string outgoingLanguages
            bool firstPacketFollows
            unit32 0 (reserved)

        Starts setting up the key exchange, keys, encryptions, and
        authentications.  Extended by ssh_KEXINIT in SSHServerTransport and
        SSHClientTransport.
        """
        self.otherKexInitPayload = chr(MSG_KEXINIT) + packet
        #cookie = packet[: 16] # taking this is useless
        k = getNS(packet[16:], 10)
        strings, rest = k[:-1], k[-1]
        (kexAlgs, keyAlgs, encCS, encSC, macCS, macSC, compCS, compSC, langCS,
         langSC) = [s.split(',') for s in strings]
        # these are the server directions
        outs = [encSC, macSC, compSC]
        ins = [encCS, macSC, compCS]
        if self.isClient:
            outs, ins = ins, outs  # switch directions
        server = (self.supportedKeyExchanges, self.supportedPublicKeys,
                  self.supportedCiphers, self.supportedCiphers,
                  self.supportedMACs, self.supportedMACs,
                  self.supportedCompressions, self.supportedCompressions)
        client = (kexAlgs, keyAlgs, outs[0], ins[0], outs[1], ins[1], outs[2],
                  ins[2])
        if self.isClient:
            server, client = client, server
        self.kexAlg = ffs(client[0], server[0])
        self.keyAlg = ffs(client[1], server[1])
        self.nextEncryptions = SSHCiphers(ffs(client[2], server[2]),
                                          ffs(client[3], server[3]),
                                          ffs(client[4], server[4]),
                                          ffs(client[5], server[5]))
        self.outgoingCompressionType = ffs(client[6], server[6])
        self.incomingCompressionType = ffs(client[7], server[7])
        if None in (self.kexAlg, self.keyAlg, self.outgoingCompressionType,
                    self.incomingCompressionType):
            self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
                                "couldn't match all kex parts")
            return
        if None in self.nextEncryptions.__dict__.values():
            self.sendDisconnect(DISCONNECT_KEY_EXCHANGE_FAILED,
                                "couldn't match all kex parts")
            return
        log.msg('kex alg, key alg: %s %s' % (self.kexAlg, self.keyAlg))
        log.msg(
            'outgoing: %s %s %s' %
            (self.nextEncryptions.outCipType, self.nextEncryptions.outMACType,
             self.outgoingCompressionType))
        log.msg('incoming: %s %s %s' %
                (self.nextEncryptions.inCipType,
                 self.nextEncryptions.inMACType, self.incomingCompressionType))
        return kexAlgs, keyAlgs, rest  # for SSHServerTransport to use
Exemple #41
0
 def request_env(self, data):
     name, rest = getNS(data)
     value, rest = getNS(rest)
     print 'request_env: %s=%s' % (name, value)
Exemple #42
0
 def request_subsystem(self, data):
     subsystem, _ = common.getNS(data)
     log.msg('asking for subsystem "{}"'.format(subsystem))
     return 0
Exemple #43
0
 def packet_DATA(self, data):
     d, data = self._parseRequest(data)
     d.callback(getNS(data)[0])
Exemple #44
0
 def packet_HANDLE(self, data):
     d, data = self._parseRequest(data)
     handle, _ = getNS(data)
     d.callback(handle)
Exemple #45
0
def unpackGlobal_tcpip_forward(data):
    host, rest = common.getNS(data)
    port = int(struct.unpack('>L', rest[:4])[0])
    return host, port
Exemple #46
0
 def auth_password(self, packet):
     password = getNS(packet[1:])[0]
     src_ip = self.transport.transport.getPeer().host
     c = credentials.UsernamePasswordIP(self.user, password, src_ip)
     return self.portal.login(
         c, src_ip, conchinterfaces.IConchUser).addErrback(self._ebPassword)
Exemple #47
0
 def _cbSignData(self, data):
     if ord(data[0]) != AGENT_SIGN_RESPONSE:
         raise ConchError('unexpected data: %i' % ord(data[0]))
     signature = getNS(data[1:])[0]
     return signature
Exemple #48
0
def unpackGlobal_tcpip_forward(data):
    host, rest = common.getNS(data)
    if _PY3 and isinstance(host, bytes):
        host = host.decode("utf-8")
    port = int(struct.unpack('>L', rest[:4])[0])
    return host, port
Exemple #49
0
    def verify(self, signature, data):
        """
        Verify a signature using this key.

        @type signature: L{bytes}
        @param signature: The signature to verify.

        @type data: L{bytes}
        @param data: The signed data.

        @rtype: L{bool}
        @return: C{True} if the signature is valid.
        """
        if len(signature) == 40:
            # DSA key with no padding
            signatureType, signature = b'ssh-dss', common.NS(signature)
        else:
            signatureType, signature = common.getNS(signature)

        if signatureType != self.sshType():
            return False

        keyType = self.type()
        if keyType == 'RSA':
            k = self._keyObject
            if not self.isPublic():
                k = k.public_key()
            args = (
                common.getNS(signature)[0],
                data,
                padding.PKCS1v15(),
                hashes.SHA1(),
            )
        elif keyType == 'DSA':
            concatenatedSignature = common.getNS(signature)[0]
            r = int_from_bytes(concatenatedSignature[:20], 'big')
            s = int_from_bytes(concatenatedSignature[20:], 'big')
            signature = encode_dss_signature(r, s)
            k = self._keyObject
            if not self.isPublic():
                k = k.public_key()
            args = (signature, data, hashes.SHA1())

        elif keyType == 'EC':  # Pragma: no branch
            concatenatedSignature = common.getNS(signature)[0]
            rstr, sstr, rest = common.getNS(concatenatedSignature, 2)
            r = int_from_bytes(rstr, 'big')
            s = int_from_bytes(sstr, 'big')
            signature = encode_dss_signature(r, s)

            k = self._keyObject
            if not self.isPublic():
                k = k.public_key()

            keySize = self.size()
            if keySize <= 256:  # Hash size depends on key size
                hashSize = hashes.SHA256()
            elif keySize <= 384:
                hashSize = hashes.SHA384()
            else:
                hashSize = hashes.SHA512()
            args = (signature, data, ec.ECDSA(hashSize))

        try:
            k.verify(*args)
        except InvalidSignature:
            return False
        else:
            return True
Exemple #50
0
 def auth_password(self, packet):
     password = getNS(packet[1:])[0]
     host = self.transport.transport.getPeer().host
     self.transport.factory.updatePot(self.user, password, host)
     return None
Exemple #51
0
 def request_exit_signal(self, data):
     signame, rest = getNS(data)
     core_dumped = struct.unpack('>?', rest[0])[0]
     msg, lang, rest = getNS(rest[1:], 2)
     self._protocol.commandExited(
         Failure(ProcessTerminated(signal=signame, status=msg)))
Exemple #52
0
 class SSHFactory(factory.SSHFactory):
     publicKeys = {common.getNS(pubkey)[0]: pubkey}
     privateKeys = {keys.objectType(privkey): privkey}
Exemple #53
0
 def request_env(self, data):
     (key, value, _) = getNS(data, count=2)
     self.env[key] = value
     return True