I'm wondering if it is possible to know if my telnet connection is successful?
So, if I'm connected to my switch and if I could write commands
telnet = telnetlib.Telnet(IP)
telnet.read_until(b"User Name:")
telnet.write(b"LOGIN\n")
telnet.read_until(b"Password:")
telnet.write(b"PASSWORD\n")
# Here I want to know if I'm connected
Don't use read_all if you plan on writing something after authentication. It blocks the connection until EOF is reached / connection is closed.
First check the output telnet server is giving when an authentication is successful using putty or something else. read_untill the string to be matched after authentication.
telnet = telnetlib.Telnet(IP)
telnet.read_until(b"User Name:")
telnet.write(b"LOGIN\n")
telnet.read_until(b"Password:")
telnet.write(b"PASSWORD\n")
telnet.read_untill("string to be matched")
You could go this way:
def is_connected(telnet_obj ):
answer = telnet_obj.read_all()
if "connected" in answer: #this test condition is not real is an example
return True
else:
return False
If you observe what yout router/switch returns you can test for that condition. In this case testing for the presence of a string or lack in the answer variable.
Related
I wrote a script a few years ago in Python 2.x and am trying to port it to run in 3.x
Here are the basics of what I am doing:
NetworkDevices is a file that contains host and access credentials for a list of devices.
DebugFile is an output file I dump stuff too as I go (depending on the debug level), so I can see when a device sent something I wasn't expecting.
NetworkDevices = open(WorkingDir + DeviceFilename,"r")
DebugFile = open(WorkingDir + DebugFilename,"w",1)
Try
# Create instance of SSHClient object
ssh_pre = paramiko.SSHClient()
# Automatically add untrusted hosts (make sure okay for security policy in your environment)
ssh_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# initiate SSH connection
ssh_pre.connect(InputVars[0], username=InputVars[1], password=InputVars[2], timeout=10)
# Use invoke_shell to establish an 'interactive session'
Conn = ssh_pre.invoke_shell()
except
# SSH connection failed, lets try a telnet connection.
Conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Open Telnet Connection to device
Conn.connect((InputVars[0],23))
except
#Print some error message saying you couldn't connect, blah blah
else
output = str(Conn.recv(10000))
else
output = str(Conn.recv(10000))
# After I establish my connection via object Conn, I can always just pull more data from
# the same connection object regardless of whether it's ssh or telnet.
if DebugVar > 3:
DebugFile.write("Here is the initial response after connecting.\n")
DebugFile.write("<<<1>>>\n"+output+"\n<<<1>>>\n")
Then do a bunch of stuff depending on what is to be collected, device type, etc.
The output I get is this:
Here is the initial response after connecting:
<<<1>>>
b'\r\nUShaBTC-DCTNW-CORE01#'
<<<1>>>
I am trying to get this:
Here is the initial response after connecting.
<<<1>>>
UShaBTC-DCTNW-CORE01#
<<<1>>>
I've tried using formatted string literals, but that keeps leading me down the path for using string slicing, which I am trying to avoid. It's a really simple thing I'm trying to do. Receive a "chunk" (to use a generic term) of data, look in that data for a certain string, keyword, or structure, then send something to the connection, and get another chunk of data.
Yes, what I'm looking for is in what I receive either way. I can still search on it, but at some point I need to write what I received out to a file that is readable, and I'm not having much luck doing that.
Hey one more question....
Apparently Python 3 doesn't support unbufferred file output. As I have shown I dump data to a debug file (depending on the debug level my script runs at). In a crash, it's pretty important to get the last bit of data that I received to figure out why it crashed, so I always wrote data received immediately with no buffering to my debug file, so I could figure out later where it crashed and why. Is there a way to write to a file in Python 3 without buffering? I dropped back to a buffer of 1 (instead of 0) so my script will run in Python 3.x, but I still might not see the last (1 byte I guess, haven't actually been able to find out what the units are for that buffer size).
Appreciate any help.
Just call decode on the byte string:
output = Conn.recv(10000).decode('utf-8')
Though in general, you should not use SSHClient.invoke_shell. Use SSHClient.exec_command. See What is the difference between exec_command and send with invoke_shell() on Paramiko?
I need to make a chat between two clients. But I don't know when a socket is closed or not, is there a way to check if it is?
Here is the part of the code that I need to fix:
def main():
"""Implements the conversation with server."""
# Open client socket, Transport layer: protocol TCP, Network layer: protocol IP
client_socket = socket.socket()
client_socket.connect((HOST_IP, PORT))
# start conversation with new client in parallel thread
name = input("enter your name ")
protocol.send_request(client_socket, name)
thread_for_responses = threading.Thread(target=get_responses,
args=(client_socket, ))
thread_for_responses.start()
while True:
# Get request from keyboard
client_request_str = input()
if client_request_str: # if client_request_str not empty string
# send request according to the protocol
protocol.send_request(client_socket, client_request_str)
# Get response from server
Instead of while True, I need to check if the socket is closed so it won't go into a loop where it will crush for using a closed socket.
Python programmers usually say it is easier to ask for forgiveness than for permission. By this they mean "handle the exception".
For example, you cannot divide by zero. Here are two ways you could deal with this fact:
def print_quotient(a, b):
if b == 0:
print("quotient is not a number")
else:
print("quotient is {}".format(a / b))
vs
def print_quotient(a, b):
try:
print("quotient is {}".format(a / b))
except ZeroDivisionError:
print("quotient is not a number")
These functions behave the same way so it doesn't make a lot of difference which approach you take. This is because b cannot change. This differs from your example where the socket can change. External factors influence its state and this changes the behavior of trying to use it (for example, to send bytes with it). In this case, exception handling is superior because it does not have to try to make sure nothing is going to go wrong, it just handles things when they go wrong. There is no case where the code thinks it has set everything up to work correctly and then it turns out it has missed something.
So, when you use socket operations, apply exception handling for any exceptions that might arise from those operations.
I plan to make a "telnet bot".
There is a game which has a telnet server built ingame, that you can turn on. Now, this telnet server logs all of the activity in the console (kills, players joining, chat, etc) and you can also type stuff into putty and it will be received ingame.
Anyway, I tried to use Python Telnetlib, but there doesn't seem to be any function that reads the last line. I also tried using sockets, but I don't quite understand the Telnet protocol.
Is there a way to use telnetlib or sockets to do the following thing?:
#def readAndDo():
serverOutput = telnet.readLastLine() #doesn't exist, this would be like the thing I need
if "> AuthorizeMe" in serverOutput.splitlines()[:-1]:
nickname = serverOutput[2:-13]
tn.write(b"playerReq = playergetByName(\"" + nickname + "\")\n")
tn.write(b"playerReq = playerInfo(\"playerReq\")\n")
username = telnet.readLastLine()
print username
readAndDo()
if "Victim" in serverOutput:
print serverOutput
readAndDo()
else:
sleep(1)
print serverOutput
readAndDo()
readAndDo()
You don't want to read the last line in telnet, but want to react on situations, where the telnet server wants input. There is no other way to parse the whole messages, the server sends and answer when the server expects answers.
I am using Python telnetlib for taking the "running config" output from router.How to store the "show running-config" output in a variable.And print the variable.My requirement is the each and every output will display in the console when executing each and every line of the code.Is there any option to aviod these print statements.
import telnetlib
#import getpass
ipaddr = "10.1.1.1"
passwd = "abcd123"
tn = telnetlib.Telnet(ipaddr)
if Password:
try:
print (tn.write (password + "\n"))
print(tn.read_until("Router>"))
print(tn.write("enable\n"))
print(tn.read_until("Password:"))
print(tn.write(passwd + "\n"))
print(tn.read_until("Router#"))
print(tn.write("show clock\n"))
print(tn.read_until("#"))
print(tn.write("show running-config\n"))
print(tn.write("\040\n"))
print(tn.write("\040\n"))
print(tn.write("\040\n"))
print(tn.read_until("#"))
print(tn.write("logout\n"))
print(tn.read_until(">"))
print tn.close
If I understand you correctly you wish to print out to your local console the output of each command which you run on the remote console. I am not sure why it needs to be synchronous except you say that is a requirement. You might want to make sure you understand the requirements. In any case, since your requirement is that the output be printed, you don't need to print your input...
I highly recommend storing the output into a variable even if you need to print it immediately simply because I see no benefit of retrieving the data unless you are going to act on the data and if you merely print the data you cannot act on it. Store it in a variable and then it can be printed as well as acted upon. I doubt the human eye would be able to tell the difference in storing it and then writing it all at once rather than piecemeal.
Your try block, as written, will never happen because you have to read from the telnet session first before you can evaluate if 'Password:' is on the remote console.
Some further suggestions:
First, write terminal length 0, that will avoid having to handle paused output.
Second, since I am lazy, any variables I know I am only using to pass to the remote unit I save with a newline character.
Third, always give it a timeout or else it runs the risk of waiting forever for a match that might never come.
Fourth, have a look at Telnet.expect(list, [timeout]). I find it far more useful than a simple read_until; it allows you to look for multiple responses and act on each of them accordingly. It is quite useful for handling errors. It returns a three item tuple that represents the index of the matched item (-1 if no match) as well as the matched text (or everything in the buffer if no match).
Fifth, write a decorator for your telnet session to log in. You know it will be used at least once every time you interact with a remote unit, and more if you are loading new firmware. Develop a library of functions that you can reuse rather than writing it out each time. Lazy is good.
import telnetlib
import sys
ipaddr = "10.1.1.1"
passwd = "abcd123"
def login(tn):
global passwd
passwd=passwd+'\n'
def error_check(tmp):
if tmp[0]==-1:
print "Unexpected response"
print "tmp[2]
sys.exit()
tmp=tn.expect(["Password:",], 5)
error_check(tmp)
tn.write(passwd)
tmp=expect([">",],5)
error_check(tmp)
tn.write('en\n')
tmp=expect(["Password", "#'],5)
error_check(tmp)
if tmp(0)==0: #if someone left enable unlocked, don't send a password
tn.write(passwd)
tmp=expect(["#',],5)
error_check(tmp)
tn = telnetlib.Telnet(ipaddr)
login(tn)
tn.write('terminal length 0')
tmp=expect(["#',],5)
tn.write('sho clock')
now=tn.expect(["#",], 5)
print now
tn.write('sho run')
print run
cfg=tn.expect(["#",], 5)
tn.write("logout\n"))
bye=tn.expect([">",], 5)
print bye
tn.close()
I'm currently working on a simple Python script that connects to an IP/Port and lets you preform commands. Kinda like telnet. I want it to connect to lets say MySQL(Just an example) and execute MySQL commands like you would with Telnet or NetCat.
But lets say I connect to a service, I can't execute commands. I'm trying to connect to a custom port on localhost. Let me show the code:
try:
sock.connect((host, port))
recvdata = sock.recv(socksize)
print("Type your commands now")
while(1): #Setting a loop
print(recvdata)
userInput = raw_input(">")
sock.send(userInput + '\r\n\r\n')
print(recvdata)
except KeyboardInterrupt:
print("\nConnection closed")
sys.exit()
So this is what I get when I connect:
:: !Test service! ::
If I type anything, I just get the banner again. The same banner over and over no matter what.
Your recvdata = sock.recv(socksize) is outside of the recv loop. I think, a good introduction to socket programming in Python might be helpful to you. Your previous question and this one would have been easily spotted by you using that introduction tutorial. Have a look at an example socket echo server/client (at this site), which you can modify further and proceed with your task. Run two separate terminals, run the echo server at one end and use the echo client with address pointint to 127.0.0.1.
Well, no wonder. You never actually call sock.recv on the communicating socket after you send your input.
Prior to the loop, recvdata contains the "banner" from the initial connect. But once you're in the loop, this variable is never changed.
I believe what you want is:
sock.connect((host, port))
recvdata = sock.recv(socksize)
print(recvdata)
print("Type your commands now")
while(1): #Setting a loop
userInput = raw_input(">")
sock.send(userInput + '\r\n\r\n')
recvdata = sock.recv(socksize)
print(recvdata)