def _ebStatus(self, reason, requestId, msg=b"request failed"): code = FX_FAILURE message = msg if isinstance(reason.value, (IOError, OSError)): if reason.value.errno == errno.ENOENT: # No such file code = FX_NO_SUCH_FILE message = ensureBytes(reason.value.strerror) elif reason.value.errno == errno.EACCES: # Permission denied code = FX_PERMISSION_DENIED message = ensureBytes(reason.value.strerror) elif reason.value.errno == errno.EEXIST: code = FX_FILE_ALREADY_EXISTS else: log.err(reason) elif isinstance(reason.value, EOFError): # EOF code = FX_EOF if reason.value.args: message = ensureBytes(reason.value.args[0]) elif isinstance(reason.value, NotImplementedError): code = FX_OP_UNSUPPORTED if reason.value.args: message = ensureBytes(reason.value.args[0]) elif isinstance(reason.value, SFTPError): code = reason.value.code message = ensureBytes(reason.value.message) else: log.err(reason) self._sendStatus(requestId, code, message)
def _packAttributes(self, attrs): flags = 0 data = b'' if 'size' in attrs: data += struct.pack('!Q', attrs['size']) flags |= FILEXFER_ATTR_SIZE if 'uid' in attrs and 'gid' in attrs: data += struct.pack('!2L', attrs['uid'], attrs['gid']) flags |= FILEXFER_ATTR_OWNERGROUP if 'permissions' in attrs: data += struct.pack('!L', attrs['permissions']) flags |= FILEXFER_ATTR_PERMISSIONS if 'atime' in attrs and 'mtime' in attrs: data += struct.pack('!2L', attrs['atime'], attrs['mtime']) flags |= FILEXFER_ATTR_ACMODTIME extended = [] for k in attrs: if k.startswith('ext_'): extType = NS(ensureBytes(k[4:])) extData = NS(attrs[k]) extended.append(extType + extData) if extended: data += struct.pack('!L', len(extended)) data += b''.join(extended) flags |= FILEXFER_ATTR_EXTENDED return struct.pack('!L', flags) + data
def processEnded(self, reason=None): """ When we are told the process ended, try to notify the other side about how the process ended using the exit-signal or exit-status requests. Also, close the channel. """ if reason is not None: err = reason.value if err.signal is not None: signame = self._getSignalName(err.signal) if (getattr(os, 'WCOREDUMP', None) is not None and os.WCOREDUMP(err.status)): log.msg('exitSignal: %s (core dumped)' % (signame, )) coreDumped = 1 else: log.msg('exitSignal: %s' % (signame, )) coreDumped = 0 self.session.conn.sendRequest( self.session, b'exit-signal', common.NS(ensureBytes(signame[3:])) + chr(coreDumped) + common.NS(b'') + common.NS(b'')) elif err.exitCode is not None: log.msg('exitCode: %r' % (err.exitCode, )) self.session.conn.sendRequest(self.session, b'exit-status', struct.pack('>L', err.exitCode)) self.session.loseConnection()
def test_ensureBytesEncodingParameter(self): """ The I{encoding} parameter is passed to L{str.encode} and selects the codec to use when converting L{unicode} to L{bytes}. """ self.assertEqual(b'\xe2\x98\x83', ensureBytes(u'\N{SNOWMAN}', encoding="utf-8"))
def test_ensureBytesErrorsParameter(self): """ The I{errors} parameter is passed to L{str.encode} and specifies the response when the input string cannot be converted according to the encoding’s rules. """ self.assertEqual( b'', ensureBytes(u'\N{SNOWMAN}', encoding="ascii", errors="ignore"))
def test_equality(self): """ Two L{HashedEntry} instances compare equal if and only if they represent the same host and key in exactly the same way: the host salt, host hash, public key type, public key, and comment fields must all be equal. """ hostSalt = b"gJbSEPBG9ZSBoZpHNtZBD1bHKBA" hostHash = b"bQv+0Xa0dByrwkA1EB0E7Xop/Fo" publicKey = Key.fromString(sampleKey) keyType = ensureBytes(publicKey.type()) comment = b"hello, world" entry = HashedEntry( hostSalt, hostHash, keyType, publicKey, comment) duplicate = HashedEntry( hostSalt, hostHash, keyType, publicKey, comment) # Vary the host salt self.assertNormalEqualityImplementation( entry, duplicate, HashedEntry( hostSalt[::-1], hostHash, keyType, publicKey, comment)) # Vary the host hash self.assertNormalEqualityImplementation( entry, duplicate, HashedEntry( hostSalt, hostHash[::-1], keyType, publicKey, comment)) # Vary the key type self.assertNormalEqualityImplementation( entry, duplicate, HashedEntry( hostSalt, hostHash, keyType[::-1], publicKey, comment)) # Vary the key self.assertNormalEqualityImplementation( entry, duplicate, HashedEntry( hostSalt, hostHash, keyType, Key.fromString(otherSampleKey), comment)) # Vary the comment self.assertNormalEqualityImplementation( entry, duplicate, HashedEntry( hostSalt, hostHash, keyType, publicKey, comment[::-1]))
def verifyHostKey(self, hostKey, fingerprint): """ Ask the L{KnownHostsFile} provider available on the factory which created this protocol this protocol to verify the given host key. @return: A L{Deferred} which fires with the result of L{KnownHostsFile.verifyHostKey}. """ hostname = self.creator.hostname ip = ensureBytes(self.transport.getPeer().host) self._state = b'SECURING' d = self.creator.knownHosts.verifyHostKey(self.creator.ui, hostname, ip, Key.fromString(hostKey)) d.addErrback(self._saveHostKeyFailure) return d
def ssh_CHANNEL_OPEN(self, packet): """ The other side wants to get a channel. Payload:: string channel name uint32 remote channel number uint32 remote window size uint32 remote maximum packet size <channel specific data> We get a channel from self.getChannel(), give it a local channel number and notify the other side. Then notify the channel by calling its channelOpen method. """ channelType, rest = common.getNS(packet) senderChannel, windowSize, maxPacket = struct.unpack('>3L', rest[:12]) packet = rest[12:] try: channel = self.getChannel(channelType, windowSize, maxPacket, packet) localChannel = self.localChannelID self.localChannelID += 1 channel.id = localChannel self.channels[localChannel] = channel self.channelsToRemoteChannel[channel] = senderChannel self.localToRemoteChannel[localChannel] = senderChannel self.transport.sendPacket( MSG_CHANNEL_OPEN_CONFIRMATION, struct.pack('>4L', senderChannel, localChannel, channel.localWindowSize, channel.localMaxPacket) + channel.specificData) log.callWithLogger(channel, channel.channelOpen, packet) except Exception as e: log.err(e, 'channel open failed') if isinstance(e, error.ConchError): textualInfo, reason = e.args if isinstance(textualInfo, (int, long)): # See #3657 and #3071 textualInfo, reason = reason, textualInfo else: reason = OPEN_CONNECT_FAILED textualInfo = "unknown failure" self.transport.sendPacket( MSG_CHANNEL_OPEN_FAILURE, struct.pack('>2L', senderChannel, reason) + common.NS(ensureBytes(textualInfo)) + common.NS(b''))
def handleInput(self, char): if char in (b'\n', b'\r'): self.escapeMode = 1 self.write(char) elif self.escapeMode == 1 and char == options['escape']: self.escapeMode = 2 elif self.escapeMode == 2: self.escapeMode = 1 # So we can chain escapes together if char == b'.': # Disconnect log.msg('disconnecting from escape') stopConnection() return elif char == b'\x1a': # ^Z, suspend def _(): _leaveRawMode() sys.stdout.flush() sys.stdin.flush() os.kill(os.getpid(), signal.SIGTSTP) _enterRawMode() reactor.callLater(0, _) return elif char == b'R': # Rekey connection log.msg('rekeying connection') self.conn.transport.sendKexInit() return elif char == b'#': # Display connections self.stdio.write( b'\r\nThe following connections are open:\r\n') channels = self.conn.channels.keys() channels.sort() for channelId in channels: self.stdio.write(ensureBytes(' #{} {}\r\n'.format( channelId, self.conn.channels[channelId]))) return self.write(b'~' + char) else: self.escapeMode = 0 self.write(char)
def _cbOpenDirectory(self, dirObj, requestId): handle = ensureBytes((str(hash(dirObj)))) if handle in self.openDirs: raise KeyError("already opened this directory") self.openDirs[handle] = [ensureBytes(dirObj), iter(dirObj)] self.sendPacket(FXP_HANDLE, requestId + NS(handle))
def _cbOpenFile(self, fileObj, requestId): fileId = ensureBytes(str(hash(fileObj))) if fileId in self.openFiles: raise KeyError('id already open') self.openFiles[fileId] = fileObj self.sendPacket(FXP_HANDLE, requestId + NS(fileId))
def selectGraphicRendition(self, *attributes): # each member of attributes must be a native string attrs = [] for a in attributes: attrs.append(ensureBytes(a)) self.write(b'\x1b[' + b';'.join(attrs) + b'm')
MSG_REQUEST_SUCCESS = 81 MSG_REQUEST_FAILURE = 82 MSG_CHANNEL_OPEN = 90 MSG_CHANNEL_OPEN_CONFIRMATION = 91 MSG_CHANNEL_OPEN_FAILURE = 92 MSG_CHANNEL_WINDOW_ADJUST = 93 MSG_CHANNEL_DATA = 94 MSG_CHANNEL_EXTENDED_DATA = 95 MSG_CHANNEL_EOF = 96 MSG_CHANNEL_CLOSE = 97 MSG_CHANNEL_REQUEST = 98 MSG_CHANNEL_SUCCESS = 99 MSG_CHANNEL_FAILURE = 100 OPEN_ADMINISTRATIVELY_PROHIBITED = 1 OPEN_CONNECT_FAILED = 2 OPEN_UNKNOWN_CHANNEL_TYPE = 3 OPEN_RESOURCE_SHORTAGE = 4 EXTENDED_DATA_STDERR = 1 messages = {} for name, value in locals().copy().items(): if name[:4] == 'MSG_': messages[value] = name # Doesn't handle doubles alphanums = ensureBytes(string.ascii_letters + string.digits) TRANSLATE_TABLE = b''.join( [chr(i) in alphanums and chr(i) or b'_' for i in range(256)]) SSHConnection.protocolMessages = messages
def test_ensureBytesBytes(self): """ L{ensureBytes} just returns any L{bytes} passed to it. """ self.assertEqual(b'\xe2\x98\x83', ensureBytes(b'\xe2\x98\x83'))
def test_ensureBytesUnicode(self): """ If L{unicode} is passed to L{ensureBytes}, the L{unicode} is converted to L{bytes} and returned. """ self.assertEqual(b"hello", ensureBytes(u"hello"))