You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ke...@apache.org on 2012/07/06 23:28:48 UTC
[3/9] [Defect / Enhancement / New Feature] CS-15281 : Removal of
third party dependencies in Citrix code base
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/channel.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/channel.py b/tools/migration/paramiko/channel.py
deleted file mode 100644
index d30496c..0000000
--- a/tools/migration/paramiko/channel.py
+++ /dev/null
@@ -1,1231 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-Abstraction for an SSH2 channel.
-"""
-
-import binascii
-import sys
-import time
-import threading
-import socket
-import os
-
-from paramiko.common import *
-from paramiko import util
-from paramiko.message import Message
-from paramiko.ssh_exception import SSHException
-from paramiko.file import BufferedFile
-from paramiko.buffered_pipe import BufferedPipe, PipeTimeout
-from paramiko import pipe
-
-
-# lower bound on the max packet size we'll accept from the remote host
-MIN_PACKET_SIZE = 1024
-
-
-class Channel (object):
- """
- A secure tunnel across an SSH L{Transport}. A Channel is meant to behave
- like a socket, and has an API that should be indistinguishable from the
- python socket API.
-
- Because SSH2 has a windowing kind of flow control, if you stop reading data
- from a Channel and its buffer fills up, the server will be unable to send
- you any more data until you read some of it. (This won't affect other
- channels on the same transport -- all channels on a single transport are
- flow-controlled independently.) Similarly, if the server isn't reading
- data you send, calls to L{send} may block, unless you set a timeout. This
- is exactly like a normal network socket, so it shouldn't be too surprising.
- """
-
- def __init__(self, chanid):
- """
- Create a new channel. The channel is not associated with any
- particular session or L{Transport} until the Transport attaches it.
- Normally you would only call this method from the constructor of a
- subclass of L{Channel}.
-
- @param chanid: the ID of this channel, as passed by an existing
- L{Transport}.
- @type chanid: int
- """
- self.chanid = chanid
- self.remote_chanid = 0
- self.transport = None
- self.active = False
- self.eof_received = 0
- self.eof_sent = 0
- self.in_buffer = BufferedPipe()
- self.in_stderr_buffer = BufferedPipe()
- self.timeout = None
- self.closed = False
- self.ultra_debug = False
- self.lock = threading.Lock()
- self.out_buffer_cv = threading.Condition(self.lock)
- self.in_window_size = 0
- self.out_window_size = 0
- self.in_max_packet_size = 0
- self.out_max_packet_size = 0
- self.in_window_threshold = 0
- self.in_window_sofar = 0
- self.status_event = threading.Event()
- self._name = str(chanid)
- self.logger = util.get_logger('paramiko.transport')
- self._pipe = None
- self.event = threading.Event()
- self.event_ready = False
- self.combine_stderr = False
- self.exit_status = -1
- self.origin_addr = None
-
- def __del__(self):
- try:
- self.close()
- except:
- pass
-
- def __repr__(self):
- """
- Return a string representation of this object, for debugging.
-
- @rtype: str
- """
- out = '<paramiko.Channel %d' % self.chanid
- if self.closed:
- out += ' (closed)'
- elif self.active:
- if self.eof_received:
- out += ' (EOF received)'
- if self.eof_sent:
- out += ' (EOF sent)'
- out += ' (open) window=%d' % (self.out_window_size)
- if len(self.in_buffer) > 0:
- out += ' in-buffer=%d' % (len(self.in_buffer),)
- out += ' -> ' + repr(self.transport)
- out += '>'
- return out
-
- def get_pty(self, term='vt100', width=80, height=24):
- """
- Request a pseudo-terminal from the server. This is usually used right
- after creating a client channel, to ask the server to provide some
- basic terminal semantics for a shell invoked with L{invoke_shell}.
- It isn't necessary (or desirable) to call this method if you're going
- to exectue a single command with L{exec_command}.
-
- @param term: the terminal type to emulate (for example, C{'vt100'})
- @type term: str
- @param width: width (in characters) of the terminal screen
- @type width: int
- @param height: height (in characters) of the terminal screen
- @type height: int
-
- @raise SSHException: if the request was rejected or the channel was
- closed
- """
- if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('pty-req')
- m.add_boolean(True)
- m.add_string(term)
- m.add_int(width)
- m.add_int(height)
- # pixel height, width (usually useless)
- m.add_int(0).add_int(0)
- m.add_string('')
- self._event_pending()
- self.transport._send_user_message(m)
- self._wait_for_event()
-
- def invoke_shell(self):
- """
- Request an interactive shell session on this channel. If the server
- allows it, the channel will then be directly connected to the stdin,
- stdout, and stderr of the shell.
-
- Normally you would call L{get_pty} before this, in which case the
- shell will operate through the pty, and the channel will be connected
- to the stdin and stdout of the pty.
-
- When the shell exits, the channel will be closed and can't be reused.
- You must open a new channel if you wish to open another shell.
-
- @raise SSHException: if the request was rejected or the channel was
- closed
- """
- if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('shell')
- m.add_boolean(1)
- self._event_pending()
- self.transport._send_user_message(m)
- self._wait_for_event()
-
- def exec_command(self, command):
- """
- Execute a command on the server. If the server allows it, the channel
- will then be directly connected to the stdin, stdout, and stderr of
- the command being executed.
-
- When the command finishes executing, the channel will be closed and
- can't be reused. You must open a new channel if you wish to execute
- another command.
-
- @param command: a shell command to execute.
- @type command: str
-
- @raise SSHException: if the request was rejected or the channel was
- closed
- """
- if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('exec')
- m.add_boolean(True)
- m.add_string(command)
- self._event_pending()
- self.transport._send_user_message(m)
- self._wait_for_event()
-
- def invoke_subsystem(self, subsystem):
- """
- Request a subsystem on the server (for example, C{sftp}). If the
- server allows it, the channel will then be directly connected to the
- requested subsystem.
-
- When the subsystem finishes, the channel will be closed and can't be
- reused.
-
- @param subsystem: name of the subsystem being requested.
- @type subsystem: str
-
- @raise SSHException: if the request was rejected or the channel was
- closed
- """
- if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('subsystem')
- m.add_boolean(True)
- m.add_string(subsystem)
- self._event_pending()
- self.transport._send_user_message(m)
- self._wait_for_event()
-
- def resize_pty(self, width=80, height=24):
- """
- Resize the pseudo-terminal. This can be used to change the width and
- height of the terminal emulation created in a previous L{get_pty} call.
-
- @param width: new width (in characters) of the terminal screen
- @type width: int
- @param height: new height (in characters) of the terminal screen
- @type height: int
-
- @raise SSHException: if the request was rejected or the channel was
- closed
- """
- if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('window-change')
- m.add_boolean(True)
- m.add_int(width)
- m.add_int(height)
- m.add_int(0).add_int(0)
- self._event_pending()
- self.transport._send_user_message(m)
- self._wait_for_event()
-
- def exit_status_ready(self):
- """
- Return true if the remote process has exited and returned an exit
- status. You may use this to poll the process status if you don't
- want to block in L{recv_exit_status}. Note that the server may not
- return an exit status in some cases (like bad servers).
-
- @return: True if L{recv_exit_status} will return immediately
- @rtype: bool
- @since: 1.7.3
- """
- return self.closed or self.status_event.isSet()
-
- def recv_exit_status(self):
- """
- Return the exit status from the process on the server. This is
- mostly useful for retrieving the reults of an L{exec_command}.
- If the command hasn't finished yet, this method will wait until
- it does, or until the channel is closed. If no exit status is
- provided by the server, -1 is returned.
-
- @return: the exit code of the process on the server.
- @rtype: int
-
- @since: 1.2
- """
- self.status_event.wait()
- assert self.status_event.isSet()
- return self.exit_status
-
- def send_exit_status(self, status):
- """
- Send the exit status of an executed command to the client. (This
- really only makes sense in server mode.) Many clients expect to
- get some sort of status code back from an executed command after
- it completes.
-
- @param status: the exit code of the process
- @type status: int
-
- @since: 1.2
- """
- # in many cases, the channel will not still be open here.
- # that's fine.
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('exit-status')
- m.add_boolean(False)
- m.add_int(status)
- self.transport._send_user_message(m)
-
- def request_x11(self, screen_number=0, auth_protocol=None, auth_cookie=None,
- single_connection=False, handler=None):
- """
- Request an x11 session on this channel. If the server allows it,
- further x11 requests can be made from the server to the client,
- when an x11 application is run in a shell session.
-
- From RFC4254::
-
- It is RECOMMENDED that the 'x11 authentication cookie' that is
- sent be a fake, random cookie, and that the cookie be checked and
- replaced by the real cookie when a connection request is received.
-
- If you omit the auth_cookie, a new secure random 128-bit value will be
- generated, used, and returned. You will need to use this value to
- verify incoming x11 requests and replace them with the actual local
- x11 cookie (which requires some knoweldge of the x11 protocol).
-
- If a handler is passed in, the handler is called from another thread
- whenever a new x11 connection arrives. The default handler queues up
- incoming x11 connections, which may be retrieved using
- L{Transport.accept}. The handler's calling signature is::
-
- handler(channel: Channel, (address: str, port: int))
-
- @param screen_number: the x11 screen number (0, 10, etc)
- @type screen_number: int
- @param auth_protocol: the name of the X11 authentication method used;
- if none is given, C{"MIT-MAGIC-COOKIE-1"} is used
- @type auth_protocol: str
- @param auth_cookie: hexadecimal string containing the x11 auth cookie;
- if none is given, a secure random 128-bit value is generated
- @type auth_cookie: str
- @param single_connection: if True, only a single x11 connection will be
- forwarded (by default, any number of x11 connections can arrive
- over this session)
- @type single_connection: bool
- @param handler: an optional handler to use for incoming X11 connections
- @type handler: function
- @return: the auth_cookie used
- """
- if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
- if auth_protocol is None:
- auth_protocol = 'MIT-MAGIC-COOKIE-1'
- if auth_cookie is None:
- auth_cookie = binascii.hexlify(self.transport.randpool.get_bytes(16))
-
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_REQUEST))
- m.add_int(self.remote_chanid)
- m.add_string('x11-req')
- m.add_boolean(True)
- m.add_boolean(single_connection)
- m.add_string(auth_protocol)
- m.add_string(auth_cookie)
- m.add_int(screen_number)
- self._event_pending()
- self.transport._send_user_message(m)
- self._wait_for_event()
- self.transport._set_x11_handler(handler)
- return auth_cookie
-
- def get_transport(self):
- """
- Return the L{Transport} associated with this channel.
-
- @return: the L{Transport} that was used to create this channel.
- @rtype: L{Transport}
- """
- return self.transport
-
- def set_name(self, name):
- """
- Set a name for this channel. Currently it's only used to set the name
- of the channel in logfile entries. The name can be fetched with the
- L{get_name} method.
-
- @param name: new channel name
- @type name: str
- """
- self._name = name
-
- def get_name(self):
- """
- Get the name of this channel that was previously set by L{set_name}.
-
- @return: the name of this channel.
- @rtype: str
- """
- return self._name
-
- def get_id(self):
- """
- Return the ID # for this channel. The channel ID is unique across
- a L{Transport} and usually a small number. It's also the number
- passed to L{ServerInterface.check_channel_request} when determining
- whether to accept a channel request in server mode.
-
- @return: the ID of this channel.
- @rtype: int
- """
- return self.chanid
-
- def set_combine_stderr(self, combine):
- """
- Set whether stderr should be combined into stdout on this channel.
- The default is C{False}, but in some cases it may be convenient to
- have both streams combined.
-
- If this is C{False}, and L{exec_command} is called (or C{invoke_shell}
- with no pty), output to stderr will not show up through the L{recv}
- and L{recv_ready} calls. You will have to use L{recv_stderr} and
- L{recv_stderr_ready} to get stderr output.
-
- If this is C{True}, data will never show up via L{recv_stderr} or
- L{recv_stderr_ready}.
-
- @param combine: C{True} if stderr output should be combined into
- stdout on this channel.
- @type combine: bool
- @return: previous setting.
- @rtype: bool
-
- @since: 1.1
- """
- data = ''
- self.lock.acquire()
- try:
- old = self.combine_stderr
- self.combine_stderr = combine
- if combine and not old:
- # copy old stderr buffer into primary buffer
- data = self.in_stderr_buffer.empty()
- finally:
- self.lock.release()
- if len(data) > 0:
- self._feed(data)
- return old
-
-
- ### socket API
-
-
- def settimeout(self, timeout):
- """
- Set a timeout on blocking read/write operations. The C{timeout}
- argument can be a nonnegative float expressing seconds, or C{None}. If
- a float is given, subsequent channel read/write operations will raise
- a timeout exception if the timeout period value has elapsed before the
- operation has completed. Setting a timeout of C{None} disables
- timeouts on socket operations.
-
- C{chan.settimeout(0.0)} is equivalent to C{chan.setblocking(0)};
- C{chan.settimeout(None)} is equivalent to C{chan.setblocking(1)}.
-
- @param timeout: seconds to wait for a pending read/write operation
- before raising C{socket.timeout}, or C{None} for no timeout.
- @type timeout: float
- """
- self.timeout = timeout
-
- def gettimeout(self):
- """
- Returns the timeout in seconds (as a float) associated with socket
- operations, or C{None} if no timeout is set. This reflects the last
- call to L{setblocking} or L{settimeout}.
-
- @return: timeout in seconds, or C{None}.
- @rtype: float
- """
- return self.timeout
-
- def setblocking(self, blocking):
- """
- Set blocking or non-blocking mode of the channel: if C{blocking} is 0,
- the channel is set to non-blocking mode; otherwise it's set to blocking
- mode. Initially all channels are in blocking mode.
-
- In non-blocking mode, if a L{recv} call doesn't find any data, or if a
- L{send} call can't immediately dispose of the data, an error exception
- is raised. In blocking mode, the calls block until they can proceed. An
- EOF condition is considered "immediate data" for L{recv}, so if the
- channel is closed in the read direction, it will never block.
-
- C{chan.setblocking(0)} is equivalent to C{chan.settimeout(0)};
- C{chan.setblocking(1)} is equivalent to C{chan.settimeout(None)}.
-
- @param blocking: 0 to set non-blocking mode; non-0 to set blocking
- mode.
- @type blocking: int
- """
- if blocking:
- self.settimeout(None)
- else:
- self.settimeout(0.0)
-
- def getpeername(self):
- """
- Return the address of the remote side of this Channel, if possible.
- This is just a wrapper around C{'getpeername'} on the Transport, used
- to provide enough of a socket-like interface to allow asyncore to work.
- (asyncore likes to call C{'getpeername'}.)
-
- @return: the address if the remote host, if known
- @rtype: tuple(str, int)
- """
- return self.transport.getpeername()
-
- def close(self):
- """
- Close the channel. All future read/write operations on the channel
- will fail. The remote end will receive no more data (after queued data
- is flushed). Channels are automatically closed when their L{Transport}
- is closed or when they are garbage collected.
- """
- self.lock.acquire()
- try:
- # only close the pipe when the user explicitly closes the channel.
- # otherwise they will get unpleasant surprises. (and do it before
- # checking self.closed, since the remote host may have already
- # closed the connection.)
- if self._pipe is not None:
- self._pipe.close()
- self._pipe = None
-
- if not self.active or self.closed:
- return
- msgs = self._close_internal()
- finally:
- self.lock.release()
- for m in msgs:
- if m is not None:
- self.transport._send_user_message(m)
-
- def recv_ready(self):
- """
- Returns true if data is buffered and ready to be read from this
- channel. A C{False} result does not mean that the channel has closed;
- it means you may need to wait before more data arrives.
-
- @return: C{True} if a L{recv} call on this channel would immediately
- return at least one byte; C{False} otherwise.
- @rtype: boolean
- """
- return self.in_buffer.read_ready()
-
- def recv(self, nbytes):
- """
- Receive data from the channel. The return value is a string
- representing the data received. The maximum amount of data to be
- received at once is specified by C{nbytes}. If a string of length zero
- is returned, the channel stream has closed.
-
- @param nbytes: maximum number of bytes to read.
- @type nbytes: int
- @return: data.
- @rtype: str
-
- @raise socket.timeout: if no data is ready before the timeout set by
- L{settimeout}.
- """
- try:
- out = self.in_buffer.read(nbytes, self.timeout)
- except PipeTimeout, e:
- raise socket.timeout()
-
- ack = self._check_add_window(len(out))
- # no need to hold the channel lock when sending this
- if ack > 0:
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
- m.add_int(self.remote_chanid)
- m.add_int(ack)
- self.transport._send_user_message(m)
-
- return out
-
- def recv_stderr_ready(self):
- """
- Returns true if data is buffered and ready to be read from this
- channel's stderr stream. Only channels using L{exec_command} or
- L{invoke_shell} without a pty will ever have data on the stderr
- stream.
-
- @return: C{True} if a L{recv_stderr} call on this channel would
- immediately return at least one byte; C{False} otherwise.
- @rtype: boolean
-
- @since: 1.1
- """
- return self.in_stderr_buffer.read_ready()
-
- def recv_stderr(self, nbytes):
- """
- Receive data from the channel's stderr stream. Only channels using
- L{exec_command} or L{invoke_shell} without a pty will ever have data
- on the stderr stream. The return value is a string representing the
- data received. The maximum amount of data to be received at once is
- specified by C{nbytes}. If a string of length zero is returned, the
- channel stream has closed.
-
- @param nbytes: maximum number of bytes to read.
- @type nbytes: int
- @return: data.
- @rtype: str
-
- @raise socket.timeout: if no data is ready before the timeout set by
- L{settimeout}.
-
- @since: 1.1
- """
- try:
- out = self.in_stderr_buffer.read(nbytes, self.timeout)
- except PipeTimeout, e:
- raise socket.timeout()
-
- ack = self._check_add_window(len(out))
- # no need to hold the channel lock when sending this
- if ack > 0:
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
- m.add_int(self.remote_chanid)
- m.add_int(ack)
- self.transport._send_user_message(m)
-
- return out
-
- def send_ready(self):
- """
- Returns true if data can be written to this channel without blocking.
- This means the channel is either closed (so any write attempt would
- return immediately) or there is at least one byte of space in the
- outbound buffer. If there is at least one byte of space in the
- outbound buffer, a L{send} call will succeed immediately and return
- the number of bytes actually written.
-
- @return: C{True} if a L{send} call on this channel would immediately
- succeed or fail
- @rtype: boolean
- """
- self.lock.acquire()
- try:
- if self.closed or self.eof_sent:
- return True
- return self.out_window_size > 0
- finally:
- self.lock.release()
-
- def send(self, s):
- """
- Send data to the channel. Returns the number of bytes sent, or 0 if
- the channel stream is closed. Applications are responsible for
- checking that all data has been sent: if only some of the data was
- transmitted, the application needs to attempt delivery of the remaining
- data.
-
- @param s: data to send
- @type s: str
- @return: number of bytes actually sent
- @rtype: int
-
- @raise socket.timeout: if no data could be sent before the timeout set
- by L{settimeout}.
- """
- size = len(s)
- self.lock.acquire()
- try:
- size = self._wait_for_send_window(size)
- if size == 0:
- # eof or similar
- return 0
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_DATA))
- m.add_int(self.remote_chanid)
- m.add_string(s[:size])
- finally:
- self.lock.release()
- # Note: We release self.lock before calling _send_user_message.
- # Otherwise, we can deadlock during re-keying.
- self.transport._send_user_message(m)
- return size
-
- def send_stderr(self, s):
- """
- Send data to the channel on the "stderr" stream. This is normally
- only used by servers to send output from shell commands -- clients
- won't use this. Returns the number of bytes sent, or 0 if the channel
- stream is closed. Applications are responsible for checking that all
- data has been sent: if only some of the data was transmitted, the
- application needs to attempt delivery of the remaining data.
-
- @param s: data to send.
- @type s: str
- @return: number of bytes actually sent.
- @rtype: int
-
- @raise socket.timeout: if no data could be sent before the timeout set
- by L{settimeout}.
-
- @since: 1.1
- """
- size = len(s)
- self.lock.acquire()
- try:
- size = self._wait_for_send_window(size)
- if size == 0:
- # eof or similar
- return 0
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_EXTENDED_DATA))
- m.add_int(self.remote_chanid)
- m.add_int(1)
- m.add_string(s[:size])
- finally:
- self.lock.release()
- # Note: We release self.lock before calling _send_user_message.
- # Otherwise, we can deadlock during re-keying.
- self.transport._send_user_message(m)
- return size
-
- def sendall(self, s):
- """
- Send data to the channel, without allowing partial results. Unlike
- L{send}, this method continues to send data from the given string until
- either all data has been sent or an error occurs. Nothing is returned.
-
- @param s: data to send.
- @type s: str
-
- @raise socket.timeout: if sending stalled for longer than the timeout
- set by L{settimeout}.
- @raise socket.error: if an error occured before the entire string was
- sent.
-
- @note: If the channel is closed while only part of the data hase been
- sent, there is no way to determine how much data (if any) was sent.
- This is irritating, but identically follows python's API.
- """
- while s:
- if self.closed:
- # this doesn't seem useful, but it is the documented behavior of Socket
- raise socket.error('Socket is closed')
- sent = self.send(s)
- s = s[sent:]
- return None
-
- def sendall_stderr(self, s):
- """
- Send data to the channel's "stderr" stream, without allowing partial
- results. Unlike L{send_stderr}, this method continues to send data
- from the given string until all data has been sent or an error occurs.
- Nothing is returned.
-
- @param s: data to send to the client as "stderr" output.
- @type s: str
-
- @raise socket.timeout: if sending stalled for longer than the timeout
- set by L{settimeout}.
- @raise socket.error: if an error occured before the entire string was
- sent.
-
- @since: 1.1
- """
- while s:
- if self.closed:
- raise socket.error('Socket is closed')
- sent = self.send_stderr(s)
- s = s[sent:]
- return None
-
- def makefile(self, *params):
- """
- Return a file-like object associated with this channel. The optional
- C{mode} and C{bufsize} arguments are interpreted the same way as by
- the built-in C{file()} function in python.
-
- @return: object which can be used for python file I/O.
- @rtype: L{ChannelFile}
- """
- return ChannelFile(*([self] + list(params)))
-
- def makefile_stderr(self, *params):
- """
- Return a file-like object associated with this channel's stderr
- stream. Only channels using L{exec_command} or L{invoke_shell}
- without a pty will ever have data on the stderr stream.
-
- The optional C{mode} and C{bufsize} arguments are interpreted the
- same way as by the built-in C{file()} function in python. For a
- client, it only makes sense to open this file for reading. For a
- server, it only makes sense to open this file for writing.
-
- @return: object which can be used for python file I/O.
- @rtype: L{ChannelFile}
-
- @since: 1.1
- """
- return ChannelStderrFile(*([self] + list(params)))
-
- def fileno(self):
- """
- Returns an OS-level file descriptor which can be used for polling, but
- but I{not} for reading or writing. This is primaily to allow python's
- C{select} module to work.
-
- The first time C{fileno} is called on a channel, a pipe is created to
- simulate real OS-level file descriptor (FD) behavior. Because of this,
- two OS-level FDs are created, which will use up FDs faster than normal.
- (You won't notice this effect unless you have hundreds of channels
- open at the same time.)
-
- @return: an OS-level file descriptor
- @rtype: int
-
- @warning: This method causes channel reads to be slightly less
- efficient.
- """
- self.lock.acquire()
- try:
- if self._pipe is not None:
- return self._pipe.fileno()
- # create the pipe and feed in any existing data
- self._pipe = pipe.make_pipe()
- p1, p2 = pipe.make_or_pipe(self._pipe)
- self.in_buffer.set_event(p1)
- self.in_stderr_buffer.set_event(p2)
- return self._pipe.fileno()
- finally:
- self.lock.release()
-
- def shutdown(self, how):
- """
- Shut down one or both halves of the connection. If C{how} is 0,
- further receives are disallowed. If C{how} is 1, further sends
- are disallowed. If C{how} is 2, further sends and receives are
- disallowed. This closes the stream in one or both directions.
-
- @param how: 0 (stop receiving), 1 (stop sending), or 2 (stop
- receiving and sending).
- @type how: int
- """
- if (how == 0) or (how == 2):
- # feign "read" shutdown
- self.eof_received = 1
- if (how == 1) or (how == 2):
- self.lock.acquire()
- try:
- m = self._send_eof()
- finally:
- self.lock.release()
- if m is not None:
- self.transport._send_user_message(m)
-
- def shutdown_read(self):
- """
- Shutdown the receiving side of this socket, closing the stream in
- the incoming direction. After this call, future reads on this
- channel will fail instantly. This is a convenience method, equivalent
- to C{shutdown(0)}, for people who don't make it a habit to
- memorize unix constants from the 1970s.
-
- @since: 1.2
- """
- self.shutdown(0)
-
- def shutdown_write(self):
- """
- Shutdown the sending side of this socket, closing the stream in
- the outgoing direction. After this call, future writes on this
- channel will fail instantly. This is a convenience method, equivalent
- to C{shutdown(1)}, for people who don't make it a habit to
- memorize unix constants from the 1970s.
-
- @since: 1.2
- """
- self.shutdown(1)
-
-
- ### calls from Transport
-
-
- def _set_transport(self, transport):
- self.transport = transport
- self.logger = util.get_logger(self.transport.get_log_channel())
-
- def _set_window(self, window_size, max_packet_size):
- self.in_window_size = window_size
- self.in_max_packet_size = max_packet_size
- # threshold of bytes we receive before we bother to send a window update
- self.in_window_threshold = window_size // 10
- self.in_window_sofar = 0
- self._log(DEBUG, 'Max packet in: %d bytes' % max_packet_size)
-
- def _set_remote_channel(self, chanid, window_size, max_packet_size):
- self.remote_chanid = chanid
- self.out_window_size = window_size
- self.out_max_packet_size = max(max_packet_size, MIN_PACKET_SIZE)
- self.active = 1
- self._log(DEBUG, 'Max packet out: %d bytes' % max_packet_size)
-
- def _request_success(self, m):
- self._log(DEBUG, 'Sesch channel %d request ok' % self.chanid)
- self.event_ready = True
- self.event.set()
- return
-
- def _request_failed(self, m):
- self.lock.acquire()
- try:
- msgs = self._close_internal()
- finally:
- self.lock.release()
- for m in msgs:
- if m is not None:
- self.transport._send_user_message(m)
-
- def _feed(self, m):
- if type(m) is str:
- # passed from _feed_extended
- s = m
- else:
- s = m.get_string()
- self.in_buffer.feed(s)
-
- def _feed_extended(self, m):
- code = m.get_int()
- s = m.get_string()
- if code != 1:
- self._log(ERROR, 'unknown extended_data type %d; discarding' % code)
- return
- if self.combine_stderr:
- self._feed(s)
- else:
- self.in_stderr_buffer.feed(s)
-
- def _window_adjust(self, m):
- nbytes = m.get_int()
- self.lock.acquire()
- try:
- if self.ultra_debug:
- self._log(DEBUG, 'window up %d' % nbytes)
- self.out_window_size += nbytes
- self.out_buffer_cv.notifyAll()
- finally:
- self.lock.release()
-
- def _handle_request(self, m):
- key = m.get_string()
- want_reply = m.get_boolean()
- server = self.transport.server_object
- ok = False
- if key == 'exit-status':
- self.exit_status = m.get_int()
- self.status_event.set()
- ok = True
- elif key == 'xon-xoff':
- # ignore
- ok = True
- elif key == 'pty-req':
- term = m.get_string()
- width = m.get_int()
- height = m.get_int()
- pixelwidth = m.get_int()
- pixelheight = m.get_int()
- modes = m.get_string()
- if server is None:
- ok = False
- else:
- ok = server.check_channel_pty_request(self, term, width, height, pixelwidth,
- pixelheight, modes)
- elif key == 'shell':
- if server is None:
- ok = False
- else:
- ok = server.check_channel_shell_request(self)
- elif key == 'exec':
- cmd = m.get_string()
- if server is None:
- ok = False
- else:
- ok = server.check_channel_exec_request(self, cmd)
- elif key == 'subsystem':
- name = m.get_string()
- if server is None:
- ok = False
- else:
- ok = server.check_channel_subsystem_request(self, name)
- elif key == 'window-change':
- width = m.get_int()
- height = m.get_int()
- pixelwidth = m.get_int()
- pixelheight = m.get_int()
- if server is None:
- ok = False
- else:
- ok = server.check_channel_window_change_request(self, width, height, pixelwidth,
- pixelheight)
- elif key == 'x11-req':
- single_connection = m.get_boolean()
- auth_proto = m.get_string()
- auth_cookie = m.get_string()
- screen_number = m.get_int()
- if server is None:
- ok = False
- else:
- ok = server.check_channel_x11_request(self, single_connection,
- auth_proto, auth_cookie, screen_number)
- else:
- self._log(DEBUG, 'Unhandled channel request "%s"' % key)
- ok = False
- if want_reply:
- m = Message()
- if ok:
- m.add_byte(chr(MSG_CHANNEL_SUCCESS))
- else:
- m.add_byte(chr(MSG_CHANNEL_FAILURE))
- m.add_int(self.remote_chanid)
- self.transport._send_user_message(m)
-
- def _handle_eof(self, m):
- self.lock.acquire()
- try:
- if not self.eof_received:
- self.eof_received = True
- self.in_buffer.close()
- self.in_stderr_buffer.close()
- if self._pipe is not None:
- self._pipe.set_forever()
- finally:
- self.lock.release()
- self._log(DEBUG, 'EOF received (%s)', self._name)
-
- def _handle_close(self, m):
- self.lock.acquire()
- try:
- msgs = self._close_internal()
- self.transport._unlink_channel(self.chanid)
- finally:
- self.lock.release()
- for m in msgs:
- if m is not None:
- self.transport._send_user_message(m)
-
-
- ### internals...
-
-
- def _log(self, level, msg, *args):
- self.logger.log(level, "[chan " + self._name + "] " + msg, *args)
-
- def _event_pending(self):
- self.event.clear()
- self.event_ready = False
-
- def _wait_for_event(self):
- self.event.wait()
- assert self.event.isSet()
- if self.event_ready:
- return
- e = self.transport.get_exception()
- if e is None:
- e = SSHException('Channel closed.')
- raise e
-
- def _set_closed(self):
- # you are holding the lock.
- self.closed = True
- self.in_buffer.close()
- self.in_stderr_buffer.close()
- self.out_buffer_cv.notifyAll()
- # Notify any waiters that we are closed
- self.event.set()
- self.status_event.set()
- if self._pipe is not None:
- self._pipe.set_forever()
-
- def _send_eof(self):
- # you are holding the lock.
- if self.eof_sent:
- return None
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_EOF))
- m.add_int(self.remote_chanid)
- self.eof_sent = True
- self._log(DEBUG, 'EOF sent (%s)', self._name)
- return m
-
- def _close_internal(self):
- # you are holding the lock.
- if not self.active or self.closed:
- return None, None
- m1 = self._send_eof()
- m2 = Message()
- m2.add_byte(chr(MSG_CHANNEL_CLOSE))
- m2.add_int(self.remote_chanid)
- self._set_closed()
- # can't unlink from the Transport yet -- the remote side may still
- # try to send meta-data (exit-status, etc)
- return m1, m2
-
- def _unlink(self):
- # server connection could die before we become active: still signal the close!
- if self.closed:
- return
- self.lock.acquire()
- try:
- self._set_closed()
- self.transport._unlink_channel(self.chanid)
- finally:
- self.lock.release()
-
- def _check_add_window(self, n):
- self.lock.acquire()
- try:
- if self.closed or self.eof_received or not self.active:
- return 0
- if self.ultra_debug:
- self._log(DEBUG, 'addwindow %d' % n)
- self.in_window_sofar += n
- if self.in_window_sofar <= self.in_window_threshold:
- return 0
- if self.ultra_debug:
- self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
- out = self.in_window_sofar
- self.in_window_sofar = 0
- return out
- finally:
- self.lock.release()
-
- def _wait_for_send_window(self, size):
- """
- (You are already holding the lock.)
- Wait for the send window to open up, and allocate up to C{size} bytes
- for transmission. If no space opens up before the timeout, a timeout
- exception is raised. Returns the number of bytes available to send
- (may be less than requested).
- """
- # you are already holding the lock
- if self.closed or self.eof_sent:
- return 0
- if self.out_window_size == 0:
- # should we block?
- if self.timeout == 0.0:
- raise socket.timeout()
- # loop here in case we get woken up but a different thread has filled the buffer
- timeout = self.timeout
- while self.out_window_size == 0:
- if self.closed or self.eof_sent:
- return 0
- then = time.time()
- self.out_buffer_cv.wait(timeout)
- if timeout != None:
- timeout -= time.time() - then
- if timeout <= 0.0:
- raise socket.timeout()
- # we have some window to squeeze into
- if self.closed or self.eof_sent:
- return 0
- if self.out_window_size < size:
- size = self.out_window_size
- if self.out_max_packet_size - 64 < size:
- size = self.out_max_packet_size - 64
- self.out_window_size -= size
- if self.ultra_debug:
- self._log(DEBUG, 'window down to %d' % self.out_window_size)
- return size
-
-
-class ChannelFile (BufferedFile):
- """
- A file-like wrapper around L{Channel}. A ChannelFile is created by calling
- L{Channel.makefile}.
-
- @bug: To correctly emulate the file object created from a socket's
- C{makefile} method, a L{Channel} and its C{ChannelFile} should be able
- to be closed or garbage-collected independently. Currently, closing
- the C{ChannelFile} does nothing but flush the buffer.
- """
-
- def __init__(self, channel, mode = 'r', bufsize = -1):
- self.channel = channel
- BufferedFile.__init__(self)
- self._set_mode(mode, bufsize)
-
- def __repr__(self):
- """
- Returns a string representation of this object, for debugging.
-
- @rtype: str
- """
- return '<paramiko.ChannelFile from ' + repr(self.channel) + '>'
-
- def _read(self, size):
- return self.channel.recv(size)
-
- def _write(self, data):
- self.channel.sendall(data)
- return len(data)
-
-
-class ChannelStderrFile (ChannelFile):
- def __init__(self, channel, mode = 'r', bufsize = -1):
- ChannelFile.__init__(self, channel, mode, bufsize)
-
- def _read(self, size):
- return self.channel.recv_stderr(size)
-
- def _write(self, data):
- self.channel.sendall_stderr(data)
- return len(data)
-
-
-# vim: set shiftwidth=4 expandtab :
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/client.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/client.py b/tools/migration/paramiko/client.py
deleted file mode 100644
index b9fe546..0000000
--- a/tools/migration/paramiko/client.py
+++ /dev/null
@@ -1,483 +0,0 @@
-# Copyright (C) 2006-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-L{SSHClient}.
-"""
-
-from binascii import hexlify
-import getpass
-import os
-import socket
-import warnings
-
-from paramiko.agent import Agent
-from paramiko.common import *
-from paramiko.dsskey import DSSKey
-from paramiko.hostkeys import HostKeys
-from paramiko.resource import ResourceManager
-from paramiko.rsakey import RSAKey
-from paramiko.ssh_exception import SSHException, BadHostKeyException
-from paramiko.transport import Transport
-
-
-SSH_PORT = 22
-
-class MissingHostKeyPolicy (object):
- """
- Interface for defining the policy that L{SSHClient} should use when the
- SSH server's hostname is not in either the system host keys or the
- application's keys. Pre-made classes implement policies for automatically
- adding the key to the application's L{HostKeys} object (L{AutoAddPolicy}),
- and for automatically rejecting the key (L{RejectPolicy}).
-
- This function may be used to ask the user to verify the key, for example.
- """
-
- def missing_host_key(self, client, hostname, key):
- """
- Called when an L{SSHClient} receives a server key for a server that
- isn't in either the system or local L{HostKeys} object. To accept
- the key, simply return. To reject, raised an exception (which will
- be passed to the calling application).
- """
- pass
-
-
-class AutoAddPolicy (MissingHostKeyPolicy):
- """
- Policy for automatically adding the hostname and new host key to the
- local L{HostKeys} object, and saving it. This is used by L{SSHClient}.
- """
-
- def missing_host_key(self, client, hostname, key):
- client._host_keys.add(hostname, key.get_name(), key)
- if client._host_keys_filename is not None:
- client.save_host_keys(client._host_keys_filename)
- client._log(DEBUG, 'Adding %s host key for %s: %s' %
- (key.get_name(), hostname, hexlify(key.get_fingerprint())))
-
-
-class RejectPolicy (MissingHostKeyPolicy):
- """
- Policy for automatically rejecting the unknown hostname & key. This is
- used by L{SSHClient}.
- """
-
- def missing_host_key(self, client, hostname, key):
- client._log(DEBUG, 'Rejecting %s host key for %s: %s' %
- (key.get_name(), hostname, hexlify(key.get_fingerprint())))
- raise SSHException('Unknown server %s' % hostname)
-
-
-class WarningPolicy (MissingHostKeyPolicy):
- """
- Policy for logging a python-style warning for an unknown host key, but
- accepting it. This is used by L{SSHClient}.
- """
- def missing_host_key(self, client, hostname, key):
- warnings.warn('Unknown %s host key for %s: %s' %
- (key.get_name(), hostname, hexlify(key.get_fingerprint())))
-
-
-class SSHClient (object):
- """
- A high-level representation of a session with an SSH server. This class
- wraps L{Transport}, L{Channel}, and L{SFTPClient} to take care of most
- aspects of authenticating and opening channels. A typical use case is::
-
- client = SSHClient()
- client.load_system_host_keys()
- client.connect('ssh.example.com')
- stdin, stdout, stderr = client.exec_command('ls -l')
-
- You may pass in explicit overrides for authentication and server host key
- checking. The default mechanism is to try to use local key files or an
- SSH agent (if one is running).
-
- @since: 1.6
- """
-
- def __init__(self):
- """
- Create a new SSHClient.
- """
- self._system_host_keys = HostKeys()
- self._host_keys = HostKeys()
- self._host_keys_filename = None
- self._log_channel = None
- self._policy = RejectPolicy()
- self._transport = None
-
- def load_system_host_keys(self, filename=None):
- """
- Load host keys from a system (read-only) file. Host keys read with
- this method will not be saved back by L{save_host_keys}.
-
- This method can be called multiple times. Each new set of host keys
- will be merged with the existing set (new replacing old if there are
- conflicts).
-
- If C{filename} is left as C{None}, an attempt will be made to read
- keys from the user's local "known hosts" file, as used by OpenSSH,
- and no exception will be raised if the file can't be read. This is
- probably only useful on posix.
-
- @param filename: the filename to read, or C{None}
- @type filename: str
-
- @raise IOError: if a filename was provided and the file could not be
- read
- """
- if filename is None:
- # try the user's .ssh key file, and mask exceptions
- filename = os.path.expanduser('~/.ssh/known_hosts')
- try:
- self._system_host_keys.load(filename)
- except IOError:
- pass
- return
- self._system_host_keys.load(filename)
-
- def load_host_keys(self, filename):
- """
- Load host keys from a local host-key file. Host keys read with this
- method will be checked I{after} keys loaded via L{load_system_host_keys},
- but will be saved back by L{save_host_keys} (so they can be modified).
- The missing host key policy L{AutoAddPolicy} adds keys to this set and
- saves them, when connecting to a previously-unknown server.
-
- This method can be called multiple times. Each new set of host keys
- will be merged with the existing set (new replacing old if there are
- conflicts). When automatically saving, the last hostname is used.
-
- @param filename: the filename to read
- @type filename: str
-
- @raise IOError: if the filename could not be read
- """
- self._host_keys_filename = filename
- self._host_keys.load(filename)
-
- def save_host_keys(self, filename):
- """
- Save the host keys back to a file. Only the host keys loaded with
- L{load_host_keys} (plus any added directly) will be saved -- not any
- host keys loaded with L{load_system_host_keys}.
-
- @param filename: the filename to save to
- @type filename: str
-
- @raise IOError: if the file could not be written
- """
- f = open(filename, 'w')
- f.write('# SSH host keys collected by paramiko\n')
- for hostname, keys in self._host_keys.iteritems():
- for keytype, key in keys.iteritems():
- f.write('%s %s %s\n' % (hostname, keytype, key.get_base64()))
- f.close()
-
- def get_host_keys(self):
- """
- Get the local L{HostKeys} object. This can be used to examine the
- local host keys or change them.
-
- @return: the local host keys
- @rtype: L{HostKeys}
- """
- return self._host_keys
-
- def set_log_channel(self, name):
- """
- Set the channel for logging. The default is C{"paramiko.transport"}
- but it can be set to anything you want.
-
- @param name: new channel name for logging
- @type name: str
- """
- self._log_channel = name
-
- def set_missing_host_key_policy(self, policy):
- """
- Set the policy to use when connecting to a server that doesn't have a
- host key in either the system or local L{HostKeys} objects. The
- default policy is to reject all unknown servers (using L{RejectPolicy}).
- You may substitute L{AutoAddPolicy} or write your own policy class.
-
- @param policy: the policy to use when receiving a host key from a
- previously-unknown server
- @type policy: L{MissingHostKeyPolicy}
- """
- self._policy = policy
-
- def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None,
- key_filename=None, timeout=None, allow_agent=True, look_for_keys=True):
- """
- Connect to an SSH server and authenticate to it. The server's host key
- is checked against the system host keys (see L{load_system_host_keys})
- and any local host keys (L{load_host_keys}). If the server's hostname
- is not found in either set of host keys, the missing host key policy
- is used (see L{set_missing_host_key_policy}). The default policy is
- to reject the key and raise an L{SSHException}.
-
- Authentication is attempted in the following order of priority:
-
- - The C{pkey} or C{key_filename} passed in (if any)
- - Any key we can find through an SSH agent
- - Any "id_rsa" or "id_dsa" key discoverable in C{~/.ssh/}
- - Plain username/password auth, if a password was given
-
- If a private key requires a password to unlock it, and a password is
- passed in, that password will be used to attempt to unlock the key.
-
- @param hostname: the server to connect to
- @type hostname: str
- @param port: the server port to connect to
- @type port: int
- @param username: the username to authenticate as (defaults to the
- current local username)
- @type username: str
- @param password: a password to use for authentication or for unlocking
- a private key
- @type password: str
- @param pkey: an optional private key to use for authentication
- @type pkey: L{PKey}
- @param key_filename: the filename, or list of filenames, of optional
- private key(s) to try for authentication
- @type key_filename: str or list(str)
- @param timeout: an optional timeout (in seconds) for the TCP connect
- @type timeout: float
- @param allow_agent: set to False to disable connecting to the SSH agent
- @type allow_agent: bool
- @param look_for_keys: set to False to disable searching for discoverable
- private key files in C{~/.ssh/}
- @type look_for_keys: bool
-
- @raise BadHostKeyException: if the server's host key could not be
- verified
- @raise AuthenticationException: if authentication failed
- @raise SSHException: if there was any other error connecting or
- establishing an SSH session
- @raise socket.error: if a socket error occurred while connecting
- """
- for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
- if socktype == socket.SOCK_STREAM:
- af = family
- addr = sockaddr
- break
- else:
- raise SSHException('No suitable address family for %s' % hostname)
- sock = socket.socket(af, socket.SOCK_STREAM)
- if timeout is not None:
- try:
- sock.settimeout(timeout)
- except:
- pass
- sock.connect(addr)
- t = self._transport = Transport(sock)
-
- if self._log_channel is not None:
- t.set_log_channel(self._log_channel)
- t.start_client()
- ResourceManager.register(self, t)
-
- server_key = t.get_remote_server_key()
- keytype = server_key.get_name()
-
- if port == SSH_PORT:
- server_hostkey_name = hostname
- else:
- server_hostkey_name = "[%s]:%d" % (hostname, port)
- our_server_key = self._system_host_keys.get(server_hostkey_name, {}).get(keytype, None)
- if our_server_key is None:
- our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None)
- if our_server_key is None:
- # will raise exception if the key is rejected; let that fall out
- self._policy.missing_host_key(self, server_hostkey_name, server_key)
- # if the callback returns, assume the key is ok
- our_server_key = server_key
-
- if server_key != our_server_key:
- raise BadHostKeyException(hostname, server_key, our_server_key)
-
- if username is None:
- username = getpass.getuser()
-
- if key_filename is None:
- key_filenames = []
- elif isinstance(key_filename, (str, unicode)):
- key_filenames = [ key_filename ]
- else:
- key_filenames = key_filename
- self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
-
- def close(self):
- """
- Close this SSHClient and its underlying L{Transport}.
- """
- if self._transport is None:
- return
- self._transport.close()
- self._transport = None
-
- def exec_command(self, command, bufsize=-1):
- """
- Execute a command on the SSH server. A new L{Channel} is opened and
- the requested command is executed. The command's input and output
- streams are returned as python C{file}-like objects representing
- stdin, stdout, and stderr.
-
- @param command: the command to execute
- @type command: str
- @param bufsize: interpreted the same way as by the built-in C{file()} function in python
- @type bufsize: int
- @return: the stdin, stdout, and stderr of the executing command
- @rtype: tuple(L{ChannelFile}, L{ChannelFile}, L{ChannelFile})
-
- @raise SSHException: if the server fails to execute the command
- """
- chan = self._transport.open_session()
- chan.exec_command(command)
- stdin = chan.makefile('wb', bufsize)
- stdout = chan.makefile('rb', bufsize)
- stderr = chan.makefile_stderr('rb', bufsize)
- return stdin, stdout, stderr
-
- def invoke_shell(self, term='vt100', width=80, height=24):
- """
- Start an interactive shell session on the SSH server. A new L{Channel}
- is opened and connected to a pseudo-terminal using the requested
- terminal type and size.
-
- @param term: the terminal type to emulate (for example, C{"vt100"})
- @type term: str
- @param width: the width (in characters) of the terminal window
- @type width: int
- @param height: the height (in characters) of the terminal window
- @type height: int
- @return: a new channel connected to the remote shell
- @rtype: L{Channel}
-
- @raise SSHException: if the server fails to invoke a shell
- """
- chan = self._transport.open_session()
- chan.get_pty(term, width, height)
- chan.invoke_shell()
- return chan
-
- def open_sftp(self):
- """
- Open an SFTP session on the SSH server.
-
- @return: a new SFTP session object
- @rtype: L{SFTPClient}
- """
- return self._transport.open_sftp_client()
-
- def get_transport(self):
- """
- Return the underlying L{Transport} object for this SSH connection.
- This can be used to perform lower-level tasks, like opening specific
- kinds of channels.
-
- @return: the Transport for this connection
- @rtype: L{Transport}
- """
- return self._transport
-
- def _auth(self, username, password, pkey, key_filenames, allow_agent, look_for_keys):
- """
- Try, in order:
-
- - The key passed in, if one was passed in.
- - Any key we can find through an SSH agent (if allowed).
- - Any "id_rsa" or "id_dsa" key discoverable in ~/.ssh/ (if allowed).
- - Plain username/password auth, if a password was given.
-
- (The password might be needed to unlock a private key.)
- """
- saved_exception = None
-
- if pkey is not None:
- try:
- self._log(DEBUG, 'Trying SSH key %s' % hexlify(pkey.get_fingerprint()))
- self._transport.auth_publickey(username, pkey)
- return
- except SSHException, e:
- saved_exception = e
-
- for key_filename in key_filenames:
- for pkey_class in (RSAKey, DSSKey):
- try:
- key = pkey_class.from_private_key_file(key_filename, password)
- self._log(DEBUG, 'Trying key %s from %s' % (hexlify(key.get_fingerprint()), key_filename))
- self._transport.auth_publickey(username, key)
- return
- except SSHException, e:
- saved_exception = e
-
- if allow_agent:
- for key in Agent().get_keys():
- try:
- self._log(DEBUG, 'Trying SSH agent key %s' % hexlify(key.get_fingerprint()))
- self._transport.auth_publickey(username, key)
- return
- except SSHException, e:
- saved_exception = e
-
- keyfiles = []
- rsa_key = os.path.expanduser('~/.ssh/id_rsa')
- dsa_key = os.path.expanduser('~/.ssh/id_dsa')
- if os.path.isfile(rsa_key):
- keyfiles.append((RSAKey, rsa_key))
- if os.path.isfile(dsa_key):
- keyfiles.append((DSSKey, dsa_key))
- # look in ~/ssh/ for windows users:
- rsa_key = os.path.expanduser('~/ssh/id_rsa')
- dsa_key = os.path.expanduser('~/ssh/id_dsa')
- if os.path.isfile(rsa_key):
- keyfiles.append((RSAKey, rsa_key))
- if os.path.isfile(dsa_key):
- keyfiles.append((DSSKey, dsa_key))
-
- if not look_for_keys:
- keyfiles = []
-
- for pkey_class, filename in keyfiles:
- try:
- key = pkey_class.from_private_key_file(filename, password)
- self._log(DEBUG, 'Trying discovered key %s in %s' % (hexlify(key.get_fingerprint()), filename))
- self._transport.auth_publickey(username, key)
- return
- except SSHException, e:
- saved_exception = e
- except IOError, e:
- saved_exception = e
-
- if password is not None:
- try:
- self._transport.auth_password(username, password)
- return
- except SSHException, e:
- saved_exception = e
-
- # if we got an auth-failed exception earlier, re-raise it
- if saved_exception is not None:
- raise saved_exception
- raise SSHException('No authentication methods available')
-
- def _log(self, level, msg):
- self._transport._log(level, msg)
-
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/common.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/common.py b/tools/migration/paramiko/common.py
deleted file mode 100644
index 9b4be50..0000000
--- a/tools/migration/paramiko/common.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-Common constants and global variables.
-"""
-
-MSG_DISCONNECT, MSG_IGNORE, MSG_UNIMPLEMENTED, MSG_DEBUG, MSG_SERVICE_REQUEST, \
- MSG_SERVICE_ACCEPT = range(1, 7)
-MSG_KEXINIT, MSG_NEWKEYS = range(20, 22)
-MSG_USERAUTH_REQUEST, MSG_USERAUTH_FAILURE, MSG_USERAUTH_SUCCESS, \
- MSG_USERAUTH_BANNER = range(50, 54)
-MSG_USERAUTH_PK_OK = 60
-MSG_USERAUTH_INFO_REQUEST, MSG_USERAUTH_INFO_RESPONSE = range(60, 62)
-MSG_GLOBAL_REQUEST, MSG_REQUEST_SUCCESS, MSG_REQUEST_FAILURE = range(80, 83)
-MSG_CHANNEL_OPEN, MSG_CHANNEL_OPEN_SUCCESS, MSG_CHANNEL_OPEN_FAILURE, \
- MSG_CHANNEL_WINDOW_ADJUST, MSG_CHANNEL_DATA, MSG_CHANNEL_EXTENDED_DATA, \
- MSG_CHANNEL_EOF, MSG_CHANNEL_CLOSE, MSG_CHANNEL_REQUEST, \
- MSG_CHANNEL_SUCCESS, MSG_CHANNEL_FAILURE = range(90, 101)
-
-
-MSG_NAMES = {
- MSG_DISCONNECT: 'disconnect',
- MSG_IGNORE: 'ignore',
- MSG_UNIMPLEMENTED: 'unimplemented',
- MSG_DEBUG: 'debug',
- MSG_SERVICE_REQUEST: 'service-request',
- MSG_SERVICE_ACCEPT: 'service-accept',
- MSG_KEXINIT: 'kexinit',
- MSG_NEWKEYS: 'newkeys',
- 30: 'kex30',
- 31: 'kex31',
- 32: 'kex32',
- 33: 'kex33',
- 34: 'kex34',
- MSG_USERAUTH_REQUEST: 'userauth-request',
- MSG_USERAUTH_FAILURE: 'userauth-failure',
- MSG_USERAUTH_SUCCESS: 'userauth-success',
- MSG_USERAUTH_BANNER: 'userauth--banner',
- MSG_USERAUTH_PK_OK: 'userauth-60(pk-ok/info-request)',
- MSG_USERAUTH_INFO_RESPONSE: 'userauth-info-response',
- MSG_GLOBAL_REQUEST: 'global-request',
- MSG_REQUEST_SUCCESS: 'request-success',
- MSG_REQUEST_FAILURE: 'request-failure',
- MSG_CHANNEL_OPEN: 'channel-open',
- MSG_CHANNEL_OPEN_SUCCESS: 'channel-open-success',
- MSG_CHANNEL_OPEN_FAILURE: 'channel-open-failure',
- MSG_CHANNEL_WINDOW_ADJUST: 'channel-window-adjust',
- MSG_CHANNEL_DATA: 'channel-data',
- MSG_CHANNEL_EXTENDED_DATA: 'channel-extended-data',
- MSG_CHANNEL_EOF: 'channel-eof',
- MSG_CHANNEL_CLOSE: 'channel-close',
- MSG_CHANNEL_REQUEST: 'channel-request',
- MSG_CHANNEL_SUCCESS: 'channel-success',
- MSG_CHANNEL_FAILURE: 'channel-failure'
- }
-
-
-# authentication request return codes:
-AUTH_SUCCESSFUL, AUTH_PARTIALLY_SUCCESSFUL, AUTH_FAILED = range(3)
-
-
-# channel request failed reasons:
-(OPEN_SUCCEEDED,
- OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED,
- OPEN_FAILED_CONNECT_FAILED,
- OPEN_FAILED_UNKNOWN_CHANNEL_TYPE,
- OPEN_FAILED_RESOURCE_SHORTAGE) = range(0, 5)
-
-
-CONNECTION_FAILED_CODE = {
- 1: 'Administratively prohibited',
- 2: 'Connect failed',
- 3: 'Unknown channel type',
- 4: 'Resource shortage'
-}
-
-
-DISCONNECT_SERVICE_NOT_AVAILABLE, DISCONNECT_AUTH_CANCELLED_BY_USER, \
- DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 7, 13, 14
-
-from rng import StrongLockingRandomPool
-
-# keep a crypto-strong PRNG nearby
-randpool = StrongLockingRandomPool()
-
-import sys
-if sys.version_info < (2, 3):
- try:
- import logging
- except:
- import logging22 as logging
- import select
- PY22 = True
-
- import socket
- if not hasattr(socket, 'timeout'):
- class timeout(socket.error): pass
- socket.timeout = timeout
- del timeout
-else:
- import logging
- PY22 = False
-
-
-DEBUG = logging.DEBUG
-INFO = logging.INFO
-WARNING = logging.WARNING
-ERROR = logging.ERROR
-CRITICAL = logging.CRITICAL
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/compress.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/compress.py b/tools/migration/paramiko/compress.py
deleted file mode 100644
index 6e61715..0000000
--- a/tools/migration/paramiko/compress.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-Compression implementations for a Transport.
-"""
-
-import zlib
-
-
-class ZlibCompressor (object):
- def __init__(self):
- self.z = zlib.compressobj(9)
-
- def __call__(self, data):
- return self.z.compress(data) + self.z.flush(zlib.Z_FULL_FLUSH)
-
-
-class ZlibDecompressor (object):
- def __init__(self):
- self.z = zlib.decompressobj()
-
- def __call__(self, data):
- return self.z.decompress(data)
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/config.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/config.py b/tools/migration/paramiko/config.py
deleted file mode 100644
index 93161c8..0000000
--- a/tools/migration/paramiko/config.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (C) 2006-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-L{SSHConfig}.
-"""
-
-import fnmatch
-
-
-class SSHConfig (object):
- """
- Representation of config information as stored in the format used by
- OpenSSH. Queries can be made via L{lookup}. The format is described in
- OpenSSH's C{ssh_config} man page. This class is provided primarily as a
- convenience to posix users (since the OpenSSH format is a de-facto
- standard on posix) but should work fine on Windows too.
-
- @since: 1.6
- """
-
- def __init__(self):
- """
- Create a new OpenSSH config object.
- """
- self._config = [ { 'host': '*' } ]
-
- def parse(self, file_obj):
- """
- Read an OpenSSH config from the given file object.
-
- @param file_obj: a file-like object to read the config file from
- @type file_obj: file
- """
- configs = [self._config[0]]
- for line in file_obj:
- line = line.rstrip('\n').lstrip()
- if (line == '') or (line[0] == '#'):
- continue
- if '=' in line:
- key, value = line.split('=', 1)
- key = key.strip().lower()
- else:
- # find first whitespace, and split there
- i = 0
- while (i < len(line)) and not line[i].isspace():
- i += 1
- if i == len(line):
- raise Exception('Unparsable line: %r' % line)
- key = line[:i].lower()
- value = line[i:].lstrip()
-
- if key == 'host':
- del configs[:]
- # the value may be multiple hosts, space-delimited
- for host in value.split():
- # do we have a pre-existing host config to append to?
- matches = [c for c in self._config if c['host'] == host]
- if len(matches) > 0:
- configs.append(matches[0])
- else:
- config = { 'host': host }
- self._config.append(config)
- configs.append(config)
- else:
- for config in configs:
- config[key] = value
-
- def lookup(self, hostname):
- """
- Return a dict of config options for a given hostname.
-
- The host-matching rules of OpenSSH's C{ssh_config} man page are used,
- which means that all configuration options from matching host
- specifications are merged, with more specific hostmasks taking
- precedence. In other words, if C{"Port"} is set under C{"Host *"}
- and also C{"Host *.example.com"}, and the lookup is for
- C{"ssh.example.com"}, then the port entry for C{"Host *.example.com"}
- will win out.
-
- The keys in the returned dict are all normalized to lowercase (look for
- C{"port"}, not C{"Port"}. No other processing is done to the keys or
- values.
-
- @param hostname: the hostname to lookup
- @type hostname: str
- """
- matches = [x for x in self._config if fnmatch.fnmatch(hostname, x['host'])]
- # sort in order of shortest match (usually '*') to longest
- matches.sort(lambda x,y: cmp(len(x['host']), len(y['host'])))
- ret = {}
- for m in matches:
- ret.update(m)
- del ret['host']
- return ret
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/32fef61a/tools/migration/paramiko/dsskey.py
----------------------------------------------------------------------
diff --git a/tools/migration/paramiko/dsskey.py b/tools/migration/paramiko/dsskey.py
deleted file mode 100644
index c693df9..0000000
--- a/tools/migration/paramiko/dsskey.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright (C) 2003-2007 Robey Pointer <ro...@gmail.com>
-# Copyright 2012 Citrix Systems, Inc. Licensed under the
-# Apache License, Version 2.0 (the "License"); you may not use this
-# file except in compliance with the License. Citrix Systems, Inc.
-# reserves all rights not expressly granted by the License.
-# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Automatically generated by addcopyright.py at 04/03/2012
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-"""
-L{DSSKey}
-"""
-
-from Crypto.PublicKey import DSA
-from Crypto.Hash import SHA
-
-from paramiko.common import *
-from paramiko import util
-from paramiko.ssh_exception import SSHException
-from paramiko.message import Message
-from paramiko.ber import BER, BERException
-from paramiko.pkey import PKey
-
-
-class DSSKey (PKey):
- """
- Representation of a DSS key which can be used to sign an verify SSH2
- data.
- """
-
- def __init__(self, msg=None, data=None, filename=None, password=None, vals=None, file_obj=None):
- self.p = None
- self.q = None
- self.g = None
- self.y = None
- self.x = None
- if file_obj is not None:
- self._from_private_key(file_obj, password)
- return
- if filename is not None:
- self._from_private_key_file(filename, password)
- return
- if (msg is None) and (data is not None):
- msg = Message(data)
- if vals is not None:
- self.p, self.q, self.g, self.y = vals
- else:
- if msg is None:
- raise SSHException('Key object may not be empty')
- if msg.get_string() != 'ssh-dss':
- raise SSHException('Invalid key')
- self.p = msg.get_mpint()
- self.q = msg.get_mpint()
- self.g = msg.get_mpint()
- self.y = msg.get_mpint()
- self.size = util.bit_length(self.p)
-
- def __str__(self):
- m = Message()
- m.add_string('ssh-dss')
- m.add_mpint(self.p)
- m.add_mpint(self.q)
- m.add_mpint(self.g)
- m.add_mpint(self.y)
- return str(m)
-
- def __hash__(self):
- h = hash(self.get_name())
- h = h * 37 + hash(self.p)
- h = h * 37 + hash(self.q)
- h = h * 37 + hash(self.g)
- h = h * 37 + hash(self.y)
- # h might be a long by now...
- return hash(h)
-
- def get_name(self):
- return 'ssh-dss'
-
- def get_bits(self):
- return self.size
-
- def can_sign(self):
- return self.x is not None
-
- def sign_ssh_data(self, rpool, data):
- digest = SHA.new(data).digest()
- dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q), long(self.x)))
- # generate a suitable k
- qsize = len(util.deflate_long(self.q, 0))
- while True:
- k = util.inflate_long(rpool.get_bytes(qsize), 1)
- if (k > 2) and (k < self.q):
- break
- r, s = dss.sign(util.inflate_long(digest, 1), k)
- m = Message()
- m.add_string('ssh-dss')
- # apparently, in rare cases, r or s may be shorter than 20 bytes!
- rstr = util.deflate_long(r, 0)
- sstr = util.deflate_long(s, 0)
- if len(rstr) < 20:
- rstr = '\x00' * (20 - len(rstr)) + rstr
- if len(sstr) < 20:
- sstr = '\x00' * (20 - len(sstr)) + sstr
- m.add_string(rstr + sstr)
- return m
-
- def verify_ssh_sig(self, data, msg):
- if len(str(msg)) == 40:
- # spies.com bug: signature has no header
- sig = str(msg)
- else:
- kind = msg.get_string()
- if kind != 'ssh-dss':
- return 0
- sig = msg.get_string()
-
- # pull out (r, s) which are NOT encoded as mpints
- sigR = util.inflate_long(sig[:20], 1)
- sigS = util.inflate_long(sig[20:], 1)
- sigM = util.inflate_long(SHA.new(data).digest(), 1)
-
- dss = DSA.construct((long(self.y), long(self.g), long(self.p), long(self.q)))
- return dss.verify(sigM, (sigR, sigS))
-
- def _encode_key(self):
- if self.x is None:
- raise SSHException('Not enough key information')
- keylist = [ 0, self.p, self.q, self.g, self.y, self.x ]
- try:
- b = BER()
- b.encode(keylist)
- except BERException:
- raise SSHException('Unable to create ber encoding of key')
- return str(b)
-
- def write_private_key_file(self, filename, password=None):
- self._write_private_key_file('DSA', filename, self._encode_key(), password)
-
- def write_private_key(self, file_obj, password=None):
- self._write_private_key('DSA', file_obj, self._encode_key(), password)
-
- def generate(bits=1024, progress_func=None):
- """
- Generate a new private DSS key. This factory function can be used to
- generate a new host key or authentication key.
-
- @param bits: number of bits the generated key should be.
- @type bits: int
- @param progress_func: an optional function to call at key points in
- key generation (used by C{pyCrypto.PublicKey}).
- @type progress_func: function
- @return: new private key
- @rtype: L{DSSKey}
- """
- randpool.stir()
- dsa = DSA.generate(bits, randpool.get_bytes, progress_func)
- key = DSSKey(vals=(dsa.p, dsa.q, dsa.g, dsa.y))
- key.x = dsa.x
- return key
- generate = staticmethod(generate)
-
-
- ### internals...
-
-
- def _from_private_key_file(self, filename, password):
- data = self._read_private_key_file('DSA', filename, password)
- self._decode_key(data)
-
- def _from_private_key(self, file_obj, password):
- data = self._read_private_key('DSA', file_obj, password)
- self._decode_key(data)
-
- def _decode_key(self, data):
- # private key file contains:
- # DSAPrivateKey = { version = 0, p, q, g, y, x }
- try:
- keylist = BER(data).decode()
- except BERException, x:
- raise SSHException('Unable to parse key file: ' + str(x))
- if (type(keylist) is not list) or (len(keylist) < 6) or (keylist[0] != 0):
- raise SSHException('not a valid DSA private key file (bad ber encoding)')
- self.p = keylist[1]
- self.q = keylist[2]
- self.g = keylist[3]
- self.y = keylist[4]
- self.x = keylist[5]
- self.size = util.bit_length(self.p)