1 # Copyright 2009 Shikhar Bhushan
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
18 from select import select as select
20 from session import Session, SessionError
22 logger = logging.getLogger('ncclient.ssh')
24 class SSHError(SessionError): pass
26 class SSHSession(Session):
30 MSG_DELIM_LEN = len(MSG_DELIM)
32 def __init__(self, capabilities, load_known_hosts=True,
33 missing_host_key_policy=paramiko.RejectPolicy):
34 Session.__init__(self, capabilities)
37 self._client = SSHClient()
39 self._client.load_system_host_keys()
40 self._client.set_missing_host_key_policy(missing_host_key_policy)
42 def load_host_keys(self, filename):
43 self._client.load_host_keys(filename)
45 def set_missing_host_key_policy(self, policy):
46 self._client.set_missing_host_key_policy(policy)
48 def connect(self, hostname, port=830, username=None, password=None,
49 key_filename=None, timeout=None, allow_agent=True,
51 self._client.connect(hostname, port=port, username=username,
52 password=password, key_filename=key_filename,
53 timeout=timeout, allow_agent=allow_agent,
54 look_for_keys=look_for_keys)
55 transport = self._client.get_transport()
56 self._channel = transport.open_session()
57 self._channel.invoke_subsystem('netconf')
62 self._channel.shutdown(2)
69 (r, w, e) = select([sock], [sock], [], 60)
72 self._outBuffer += ( q.get() + MSG_DELIM )
74 n = sock.send(self._outBuffer)
75 self._outBuffer = self._outBuffer[n:]
77 data = sock.recv(BUF_SIZE)
80 (before, _, after) = self._inBuf.partition(MSG_DELIM)
82 # we don't want this thread to ground to a halt
83 # because of an error dispatching one reply...
84 try: self.dispatch('reply', before)
88 self.dispatch('error', self._inBuf)
91 class CallbackPolicy(paramiko.MissingHostKeyPolicy):
93 def __init__(self, cb):
96 def missing_host_key(self, client, hostname, key):
97 if not self._cb(hostname, key):