def _ssh_channel_write(ssh_channel_int, data): data_len = len(data) sent_bytes = c_ssh_channel_write(ssh_channel_int, cast(c_char_p(data), c_void_p), c_uint32(data_len)) if sent_bytes == SSH_ERROR: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Channel write failed: %s" % (error)) elif sent_bytes != data_len: raise SshError("Channel write of (%d) bytes failed for length (%d) of " "written data." % (data_len, sent_bytes))
def _ssh_connect(ssh_session): result = c_ssh_connect(c_void_p(ssh_session)) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: error = ssh_get_error(ssh_session) raise SshError("Connect failed: %s" % (error))
def _ssh_channel_read(ssh_channel_int, count, is_stderr): """Do a read on a channel.""" buffer_ = create_string_buffer(count) while 1: received_bytes = c_ssh_channel_read(ssh_channel_int, cast(buffer_, c_void_p), c_uint32(count), c_int(int(is_stderr))) if received_bytes == SSH_ERROR: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Channel read failed: %s" % (error)) # BUG: We're not using the nonblocking variant, but this can still # return SSH_AGAIN due to that call's broken dependencies. # TODO: This call might return SSH_AGAIN, even though we should always be # blocking. Reported as bug #115. elif received_bytes == SSH_AGAIN: continue else: break # TODO: Where is the timeout configured for the read? return buffer_.raw[0:received_bytes]
def _ssh_channel_send_eof(ssh_channel_int): result = c_ssh_channel_send_eof(ssh_channel_int) if result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Could not send EOF: %s" % (error))
def _ssh_write_knownhost(ssh_session): logging.debug("Updating known-hosts file.") result = c_ssh_write_knownhost(c_void_p(ssh_session)) if result != SSH_OK: error = ssh_get_error(ssh_session) raise SshError("Could not update known-hosts file: %s" % (error))
def _ssh_channel_change_pty_size(ssh_channel_int, col, row): result = c_ssh_channel_change_pty_size(ssh_channel_int, c_int(col), c_int(row)) if result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("PTY size change failed: %s" % (error))
def _ssh_options_set_long(ssh_session, type_, value): value_long = c_long(value) result = c_ssh_options_set(c_void_p(ssh_session), c_int(type_), cast(byref(value_long), c_void_p)) if result < 0: error = ssh_get_error(ssh_session) raise SshError("Could not set LONG option (%d) to (%d): %s" % (type_, value, error))
def _ssh_get_openssh_version(ssh_session): """Returns an encoded version. Comparisons can be done with the SSH_INT_VERSION macro. """ openssh_server_version = c_ssh_get_openssh_version(c_void_p(ssh_session)) if openssh_server_version == 0: raise SshError("Could not get OpenSSH version. Server may not be " "OpenSSH.") return openssh_server_version
def _ssh_channel_new(ssh_session_int): logging.debug("Opening channel on session.") result = c_ssh_channel_new(ssh_session_int) if result is None: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Could not open channel: %s" % (error)) return result
def _ssh_channel_open_session(ssh_channel_int): logging.debug("Request channel open-session.") result = c_ssh_channel_open_session(ssh_channel_int) if result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Could not open session on channel: %s" % (error)) logging.debug("Channel open-session successful.")
def _ssh_options_set_string(ssh_session, type_, value): assert issubclass(value.__class__, str) value_charp = c_char_p(bytify(value)) result = c_ssh_options_set(c_void_p(ssh_session), c_int(type_), cast(value_charp, c_void_p)) if result < 0: error = ssh_get_error(ssh_session) raise SshError("Could not set STRING option (%d) to [%s]: %s" % (type_, value, error))
def _ssh_channel_request_pty(ssh_channel_int): logging.debug("Requesting channel PTY.") result = c_ssh_channel_request_pty(ssh_channel_int) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("PTY request failed: %s" % (error)) logging.debug("Channel PTY request successful.")
def _ssh_channel_request_exec(ssh_channel_int, cmd): logging.debug("Requesting channel exec.") result = c_ssh_channel_request_exec(ssh_channel_int, c_char_p(bytify(cmd))) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Could not execute shell request on channel: %s" % (error)) logging.debug("Channel-exec successful.")
def _ssh_channel_read_nonblocking(ssh_channel_int, count, is_stderr): buffer_ = create_string_buffer(count) received_bytes = c_ssh_channel_read_nonblocking(ssh_channel_int, cast(buffer_, c_void_p), c_uint32(count), c_int(int(is_stderr))) if received_bytes == SSH_ERROR: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Channel read (non-blocking) failed: %s" % (error)) return buffer_.raw[0:received_bytes]
def _ssh_channel_request_env(ssh_channel_int, name, value): logging.debug("Setting remote environment variable [%s] to [%s]." % (name, value)) # TODO: We haven't been able to get this to work. Reported bug #125. result = c_ssh_channel_request_env(ssh_channel_int, c_char_p(bytify(name)), c_char_p(bytify(value))) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Request-env failed: %s" % (error))
def ssh_pki_import_privkey_file(file_path, pass_phrase=None): assert issubclass(file_path.__class__, str) logging.debug("Importing private-key from [%s]." % (file_path)) key = c_ssh_key() # TODO: This needs to be freed. Use our key class. file_path = bytify(file_path) if pass_phrase is not None: assert issubclass(pass_phrase.__class__, str) pass_phrase = bytify(pass_phrase) result = c_ssh_pki_import_privkey_file(c_char_p(file_path), c_char_p(pass_phrase), None, None, byref(key)) if result == SSH_EOF: raise SshError("Key file [%s] does not exist or could not be read." % (file_path)) elif result != SSH_OK: raise SshError("Could not import key.") return key
def _ssh_channel_request_x11(ssh_channel_int, screen_number=0, single_connection=False, protocol=None, cookie=None): result = c_ssh_channel_request_x11(ssh_channel_int, int(single_connection), c_char_p(bytify(protocol)), \ c_char_p(bytify(cookie)), screen_number) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Channel request-X11 failed: %s" % (error))
def _ssh_forward_listen(ssh_session, address, port): if address is not None: assert issubclass(address.__class__, str) address = bytify(address) bound_port = c_int() # BUG: Currently always returns SSH_AGAIN in 0.6.0 . Registered as bug #126. result = c_ssh_forward_listen(ssh_session, address, port, byref(bound_port)) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: error = ssh_get_error(ssh_session) raise SshError("Forward-listen failed: %s" % (error)) return bound_port.value
def _ssh_channel_open_forward(ssh_channel_int, host_remote, port_remote, host_source, port_local): logging.debug("Requesting forward on channel.") result = c_ssh_channel_open_forward(ssh_channel_int, c_char_p(bytify(host_remote)), c_int(port_remote), c_char_p(bytify(host_source)), c_int(port_local)) if result == SSH_AGAIN: raise SshNonblockingTryAgainException() elif result != SSH_OK: ssh_session_int = _ssh_channel_get_session(ssh_channel_int) error = ssh_get_error(ssh_session_int) raise SshError("Forward failed: %s" % (error))
def open(self): for k, v in self.__options.items(): (option_id, type_) = SSH_OPTIONS[k] if type_ == 'string': option_setter = _ssh_options_set_string elif type_ == 'uint': option_setter = _ssh_options_set_uint elif type_ == 'int': option_setter = _ssh_options_set_int elif type_ == 'long': option_setter = _ssh_options_set_long elif type_ == 'bool': v = 0 if v is False else 1 option_setter = _ssh_options_set_int else: raise SshError("Option type [%s] is invalid." % (type_)) self.__log.debug("Setting option [%s] (%d) to [%s]." % (k, option_id, v)) option_setter(self.__ssh_session_ptr, option_id, v) return self
def _ssh_new(): ssh_session = c_ssh_new() if ssh_session is None: raise SshError("Could not create session.") return ssh_session
def execute_exit_code(self): try: return self.__exit_code except AttributeError: raise SshError("No command was previously executed!")
def ssh_threads_set_callbacks(cb): result = c_ssh_threads_set_callbacks(c_void_p(cb)) if result != SSH_OK: raise SshError("Could not set callbacks.")
def _ssh_get_serverbanner(ssh_session): result = c_ssh_get_serverbanner(c_void_p(ssh_session)) if result is None: raise SshError("Could not get server-banner.") return result
def _ssh_get_version(ssh_session): protocol_version = c_ssh_get_version(ssh_session) if protocol_version < 0: raise SshError("Could not determine protocol version.") return protocol_version
def _ssh_key_new(): key = c_ssh_key_new() if key is None: raise SshError("Could not create empty key.") return key
def _ssh_finalize(): result = c_ssh_finalize() if result < 0: raise SshError("Could not finalize SSH.")
def _ssh_init(): result = c_ssh_init() if result < 0: raise SshError("Could not initialize SSH.")
def _ssh_get_hexa(hash_, hlen): hexa = c_ssh_get_hexa(hash_, c_int(hlen)) if hexa is None: raise SshError("Could not build hex-string.") return hexa