root / ncclient / ssh.py @ 589b23e4
History | View | Annotate | Download (3.9 kB)
1 | 589b23e4 | Shikhar Bhushan | # Copyright 2009 Shikhar Bhushan
|
---|---|---|---|
2 | 589b23e4 | Shikhar Bhushan | #
|
3 | 589b23e4 | Shikhar Bhushan | # Licensed under the Apache License, Version 2.0 (the "License");
|
4 | 589b23e4 | Shikhar Bhushan | # you may not use this file except in compliance with the License.
|
5 | 589b23e4 | Shikhar Bhushan | # You may obtain a copy of the License at
|
6 | 589b23e4 | Shikhar Bhushan | #
|
7 | 589b23e4 | Shikhar Bhushan | # http://www.apache.org/licenses/LICENSE-2.0
|
8 | 589b23e4 | Shikhar Bhushan | #
|
9 | 589b23e4 | Shikhar Bhushan | # Unless required by applicable law or agreed to in writing, software
|
10 | 589b23e4 | Shikhar Bhushan | # distributed under the License is distributed on an "AS IS" BASIS,
|
11 | 589b23e4 | Shikhar Bhushan | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12 | 589b23e4 | Shikhar Bhushan | # See the License for the specific language governing permissions and
|
13 | 589b23e4 | Shikhar Bhushan | # limitations under the License.
|
14 | 589b23e4 | Shikhar Bhushan | |
15 | 589b23e4 | Shikhar Bhushan | import logging |
16 | 589b23e4 | Shikhar Bhushan | import paramiko |
17 | 589b23e4 | Shikhar Bhushan | |
18 | 589b23e4 | Shikhar Bhushan | from session import Session, SessionError |
19 | 589b23e4 | Shikhar Bhushan | |
20 | 589b23e4 | Shikhar Bhushan | logger = logging.getLogger('ncclient.ssh')
|
21 | 589b23e4 | Shikhar Bhushan | |
22 | 589b23e4 | Shikhar Bhushan | class SessionCloseError(SessionError): |
23 | 589b23e4 | Shikhar Bhushan | |
24 | 589b23e4 | Shikhar Bhushan | def __str__(self): |
25 | 589b23e4 | Shikhar Bhushan | return 'RECEIVED: %s | UNSENT: %s' % (self._in_buf, self._out_buf) |
26 | 589b23e4 | Shikhar Bhushan | |
27 | 589b23e4 | Shikhar Bhushan | def __init__(self, in_buf, out_buf): |
28 | 589b23e4 | Shikhar Bhushan | SessionError.__init__(self)
|
29 | 589b23e4 | Shikhar Bhushan | self._in_buf, self._out_buf = in_buf, out_buf |
30 | 589b23e4 | Shikhar Bhushan | |
31 | 589b23e4 | Shikhar Bhushan | class SSHSession(Session): |
32 | 589b23e4 | Shikhar Bhushan | |
33 | 589b23e4 | Shikhar Bhushan | BUF_SIZE = 4096
|
34 | 589b23e4 | Shikhar Bhushan | MSG_DELIM = ']]>]]>'
|
35 | 589b23e4 | Shikhar Bhushan | |
36 | 589b23e4 | Shikhar Bhushan | def __init__(self, load_known_hosts=True, |
37 | 589b23e4 | Shikhar Bhushan | missing_host_key_policy=paramiko.RejectPolicy): |
38 | 589b23e4 | Shikhar Bhushan | Session.__init__(self)
|
39 | 589b23e4 | Shikhar Bhushan | self._in_buf = '' |
40 | 589b23e4 | Shikhar Bhushan | self._out_buf = '' |
41 | 589b23e4 | Shikhar Bhushan | self._client = paramiko.SSHClient()
|
42 | 589b23e4 | Shikhar Bhushan | if load_known_hosts:
|
43 | 589b23e4 | Shikhar Bhushan | self._client.load_system_host_keys()
|
44 | 589b23e4 | Shikhar Bhushan | self._client.set_missing_host_key_policy(missing_host_key_policy)
|
45 | 589b23e4 | Shikhar Bhushan | |
46 | 589b23e4 | Shikhar Bhushan | def load_host_keys(self, filename): |
47 | 589b23e4 | Shikhar Bhushan | self._client.load_host_keys(filename)
|
48 | 589b23e4 | Shikhar Bhushan | |
49 | 589b23e4 | Shikhar Bhushan | def set_missing_host_key_policy(self, policy): |
50 | 589b23e4 | Shikhar Bhushan | self._client.set_missing_host_key_policy(policy)
|
51 | 589b23e4 | Shikhar Bhushan | |
52 | 589b23e4 | Shikhar Bhushan | # paramiko exceptions ok?
|
53 | 589b23e4 | Shikhar Bhushan | # user might be looking for ClientError
|
54 | 589b23e4 | Shikhar Bhushan | def connect(self, hostname, port=830, username=None, password=None, |
55 | 589b23e4 | Shikhar Bhushan | key_filename=None, timeout=None, allow_agent=True, |
56 | 589b23e4 | Shikhar Bhushan | look_for_keys=True):
|
57 | 589b23e4 | Shikhar Bhushan | self._client.connect(hostname, port=port, username=username,
|
58 | 589b23e4 | Shikhar Bhushan | password=password, key_filename=key_filename, |
59 | 589b23e4 | Shikhar Bhushan | timeout=timeout, allow_agent=allow_agent, |
60 | 589b23e4 | Shikhar Bhushan | look_for_keys=look_for_keys) |
61 | 589b23e4 | Shikhar Bhushan | transport = self._client.get_transport()
|
62 | 589b23e4 | Shikhar Bhushan | self._channel = transport.open_session()
|
63 | 589b23e4 | Shikhar Bhushan | self._channel.invoke_subsystem('netconf') |
64 | 589b23e4 | Shikhar Bhushan | self._channel.set_name('netconf') |
65 | 589b23e4 | Shikhar Bhushan | self._init()
|
66 | 589b23e4 | Shikhar Bhushan | |
67 | 589b23e4 | Shikhar Bhushan | def _close(self): |
68 | 589b23e4 | Shikhar Bhushan | self._channel.close()
|
69 | 589b23e4 | Shikhar Bhushan | Session._close(self)
|
70 | 589b23e4 | Shikhar Bhushan | |
71 | 589b23e4 | Shikhar Bhushan | def run(self): |
72 | 589b23e4 | Shikhar Bhushan | |
73 | 589b23e4 | Shikhar Bhushan | chan = self._channel
|
74 | 589b23e4 | Shikhar Bhushan | chan.setblocking(0)
|
75 | 589b23e4 | Shikhar Bhushan | q = self._q
|
76 | 589b23e4 | Shikhar Bhushan | |
77 | 589b23e4 | Shikhar Bhushan | while True: |
78 | 589b23e4 | Shikhar Bhushan | |
79 | 589b23e4 | Shikhar Bhushan | if chan.closed:
|
80 | 589b23e4 | Shikhar Bhushan | break
|
81 | 589b23e4 | Shikhar Bhushan | |
82 | 589b23e4 | Shikhar Bhushan | if chan.recv_ready():
|
83 | 589b23e4 | Shikhar Bhushan | data = chan.recv(SSHSession.BUF_SIZE) |
84 | 589b23e4 | Shikhar Bhushan | if data:
|
85 | 589b23e4 | Shikhar Bhushan | self._in_buf += data
|
86 | 589b23e4 | Shikhar Bhushan | while True: |
87 | 589b23e4 | Shikhar Bhushan | before, delim, after = self._in_buf.partition(SSHSession.MSG_DELIM)
|
88 | 589b23e4 | Shikhar Bhushan | if delim:
|
89 | 589b23e4 | Shikhar Bhushan | self.dispatch('reply', before) |
90 | 589b23e4 | Shikhar Bhushan | self._in_buf = after
|
91 | 589b23e4 | Shikhar Bhushan | else:
|
92 | 589b23e4 | Shikhar Bhushan | break
|
93 | 589b23e4 | Shikhar Bhushan | else:
|
94 | 589b23e4 | Shikhar Bhushan | break
|
95 | 589b23e4 | Shikhar Bhushan | |
96 | 589b23e4 | Shikhar Bhushan | if chan.send_ready():
|
97 | 589b23e4 | Shikhar Bhushan | if not q.empty(): |
98 | 589b23e4 | Shikhar Bhushan | msg = q.get() |
99 | 589b23e4 | Shikhar Bhushan | self._out_buf += ( msg + SSHSession.MSG_DELIM )
|
100 | 589b23e4 | Shikhar Bhushan | while self._out_buf: |
101 | 589b23e4 | Shikhar Bhushan | n = chan.send(self._out_buf)
|
102 | 589b23e4 | Shikhar Bhushan | if n <= 0: |
103 | 589b23e4 | Shikhar Bhushan | break
|
104 | 589b23e4 | Shikhar Bhushan | self._out_buf = self._out_buf[n:] |
105 | 589b23e4 | Shikhar Bhushan | |
106 | 589b23e4 | Shikhar Bhushan | logger.debug('** broke out of main loop **')
|
107 | 589b23e4 | Shikhar Bhushan | self.dispatch('close', SessionCloseError(self._in_buf, self._out_buf)) |
108 | 589b23e4 | Shikhar Bhushan | |
109 | 589b23e4 | Shikhar Bhushan | class MissingHostKeyPolicy(paramiko.MissingHostKeyPolicy): |
110 | 589b23e4 | Shikhar Bhushan | |
111 | 589b23e4 | Shikhar Bhushan | def __init__(self, cb): |
112 | 589b23e4 | Shikhar Bhushan | self._cb = cb
|
113 | 589b23e4 | Shikhar Bhushan | |
114 | 589b23e4 | Shikhar Bhushan | def missing_host_key(self, client, hostname, key): |
115 | 589b23e4 | Shikhar Bhushan | if not self._cb(hostname, key): |
116 | 589b23e4 | Shikhar Bhushan | raise SSHError |