1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
#!/usr/bin/env python
# -*- coding: ISO-8859-15 -*-
#
# Copyright (C) 2005-2007 David Guerizec <david@guerizec.net>
#
# Last modified: 2007 Dec 23, 19:22:18 by david
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import telnetlib
import select
from sshproxy import get_class
from sshproxy.registry import Registry
from sshproxy.server import Server
from sshproxy import log
from sshproxy.util import chanfmt
# set suboptions
#telnetlib.SEND = chr(1)
#
#tnd = {}
#for v in dir(telnetlib):
# try:
# tnd[getattr(telnetlib, v)] = v
# except TypeError:
# pass
Server = get_class('Server')
class TelnetEnabledServer(Server):
def do_shell_session(self):
site = self.args[0]
if not self.authorize(site, need_login=True):
self.chan.send(chanfmt(_(u"ERROR: %s does not exist in "
"your scope\n") % site))
return False
kind = self.get_ns_tag('site', 'kind', '')
if not kind == 'telnet':
return Server.do_shell_session(self)
else:
site = self.args.pop(0)
if not self.check_acl('telnet_session'):
self.chan.send(chanfmt("ERROR: You are not allowed to"
" open a telnet session on %s"
"\n" % site))
return False
self.update_ns('client', {
'type': 'telnet_session'
})
log.info("Connecting to %s (telnet)", site)
conn = TelnetProxy(self.chan, self.connect_telnet(), self.monitor)
try:
self.exit_status = conn.loop()
except KeyboardInterrupt:
return True
except Exception, e:
self.chan.send("\r\n ERROR: It seems you found a bug."
"\r\n Please report this error "
"to your administrator.\r\n"
"Exception class: <%s>\r\n\r\n"
% e.__class__.__name__)
log.exception("An unknown exception occured")
raise
# if the direct connection closed, then exit cleanly
conn = None
log.info("Exiting %s", site)
return True
def connect_telnet(self):
tl = telnetlib
ip_address = self.get_ns_tag("site", "ip_address")
port = self.get_ns_tag("site", "port")
user = self.get_ns_tag("site", "login")
self.tn = tn = tl.Telnet()
tn.set_option_negotiation_callback(self.parse_telnet_options)
tn.open(ip_address, int(port))
tn.sock.sendall(tl.IAC + tl.WILL + tl.NAWS)
tn.sock.sendall(tl.IAC + tl.WILL + tl.TTYPE)
timeout = 2
time = 0
total_timeout = 30
while True:
prompt = tn.expect(["(?i)SW:? ?",
"(?i)Login:? ?",
"(?i)Username:? ?"], timeout)
if prompt[0] == -1 and prompt[2].strip() == "":
tn.write("\r\n")
time += timeout
if time >= total_timeout:
raise ValueError("ERROR: Couldn't connect. Timeout reached")
timeout = 10
continue
if prompt[0] < 1:
tn.write("\031")
timeout = 10
time += timeout
continue
break
tn.write(user + "\r\n")
password = self.monitor.call("get_site_password", clear=True)
prompt = tn.expect(["(?i)Password:? ?"], 10)
if prompt[0] == -1 and prompt[2] == "":
raise ValueError("ERROR: Couldn't connect. Timeout reached")
tn.write(password + "\r\n")
return tn
def parse_telnet_options(self, sock, command, option):
tl = telnetlib
#log.devdebug("OPTION received: %s %s" % (tnd[command], tnd[option]))
#sbq = self.tn.read_sb_data()
#if len(sbq):
# log.devdebug("SB: %s" % ' '.join([ tnd[o] for o in sbq ]))
if command == tl.DO and option == tl.NAWS:
sock.sendall(tl.IAC + tl.SB +
tl.NAWS +
chr(self.width>>8) + chr(self.width&0xff) +
chr(self.height>>8) + chr(self.height&0xff) +
tl.IAC + tl.SE)
return
if command == tl.DO and option == tl.TTYPE:
sock.sendall(tl.IAC + tl.SB +
tl.TTYPE +
tl.theNULL + self.term +
tl.IAC + tl.SE)
return
if command in (tl.DO, tl.DONT):
sock.sendall(tl.IAC + tl.WONT + option)
elif command in (tl.WILL, tl.WONT):
sock.sendall(tl.IAC + tl.DONT + option)
TelnetEnabledServer.register()
class TelnetProxy(Registry):
_class_id = 'TelnetProxy'
def __reginit__(self, chan, tn, monitor):
self.chan = chan
self.tn = tn
self.monitor = monitor
def loop(self):
while True:
r, w, e = select.select([self.chan, self.tn], [], [], 0.1)
if len(r):
if self.chan in r:
data = self.chan.recv(1).replace('\r', '\r\n')
if data == '':
break
self.tn.write(data)
if self.tn in r:
try:
data = self.tn.read_very_eager()
except EOFError:
break
self.chan.send(data)
#self.chan.flush()
self.tn.close()
# if not self.chan.closed and self.chan.transport.is_active():
# self.chan.close()
return 0
TelnetProxy.register()
|