Question

I have code that is using telnet and requires a login. If the login is incorrect, it returns "Incorrect login" to the console. I want to catch this exception and skip it so it doesn't stop the program. What I tried is below:

try:
    session.write("username".encode('ascii') + b"\r")
    session.write("password".encode('ascii') + b"\r")
    ***this is the point where the console will return "Incorrect login"***
except sys.stdout == "Incorrect login":
    print(sys.stdout)
    pass
else:
    **Rest of the code**

It seems that it never catches this output, continues on to my code and ends up in an index error (from not having the data I need from logging in). I tried searching but had no luck. Any help would be appreciated. I'm running python 3.3 and am still learning. Thanks!

Edit: Here is what telnet shows

login: badusername
password: **blank b/c it is a pw field**
Login incorrect

login: 

Edit2: All code up to else (edited for confidentiality)

import telnetlib, time
import sys, string, socket
import cx_Oracle

sql = "select column from table" 
con = cx_Oracle.connect("login info blah...")
cur = con.cursor()
cur.execute(sql)
row = cur.fetchone()
rows = cur.fetchall()

def Tup():
    return (rows)

cur.close()
con.close()

i = 0

while i < len(rows):   
    host    = Tup()[i][0]
    timeout = 120
    print(host + ' =', end = ' ')
    try:
        session = telnetlib.Telnet(host, 23, timeout)
    except:
        out = open("Data.txt",'a')
        out.write(host + " = FAILED\n")
        print("FAILED")
    else:        
    try:
        session.write("username".encode('ascii') + b"\r")
        session.write("pass".encode('ascii') + b"\r")
    except sys.stdout == "Incorrect login":
        print(sys.stdout)
        pass
    else:
Was it helpful?

Solution

Take a look into [subprocess][1] module, it contains a check_output method that returns the output of the executed command as a string.

Try this. You might need to change some syntactical details...

PROMPT = '$' # or '#' or '%', the shell prompt
TIMEOUT = 3

try:
    session.read_until(b"login:")
    session.write("username".encode('ascii') + b"\r")

    session.read_until(b"password:")
    session.write("password".encode('ascii') + b"\r")
    login_result = session.read_until(PROMPT, TIMEOUT) # This will make it put whatever is printed till PROMPT into login_result. if it takes more than TIMEOUT seconds, you can assume login failed (since PROMPT never came up)
    ***this is the point where the console will return "Incorrect login"***

    if(login_result[-1] != PROMPT):    # change this -1 to -2 or -3 if the output is trailed by a newline
        raise Exception

except Exception:
    print("Login Failure")
    pass

else:
    **Rest of the code**

OTHER TIPS

If you take a look into the python 'telnetlib.py' code, you'll see a method called 'expect()'. You might give it a try to see if it will help you get the job done. Keep in mind that it's expecting a list of regex, so design your search strings accordingly.

Since you're using telnetlib, if you haven't already stumbled on this tip yet (I sure used telnetlib a long time without noticing it) try setting the telnet.debuglevel to non-zero. It may help you in snooping the low-level data traffic.

Edit:

Well, I found myself with some time on my hands, so I was able to create and test some demo code. First off, just know that as a beginner, you've chosen to dive into a "deeper" end of the coding pool by playing with telnetlib and expect. They're not hard, but they are tedious due to the arcana of both telnet and the "art" of screen-scraping. Not for the weak of heart.

So here's my cut. I tested this on one of our local servers and was able to change to a invalid password to verify that the code did detect a "Login failed" condition. You may very well need to tweak this code for your application.

#!/usr/bin/python3

import telnetlib

TARGET_NAME = "<insert yours here>"
USER_NAME   = "<insert yours here>"
USER_PW     = "<insert yours here>"

session = telnetlib.Telnet(host=TARGET_NAME)

session.debuglevel = 1

session.write("\n\n".encode('ascii'))

index, match_obj, text = session.expect(["login: ".encode('ascii')])
if match_obj:
    print("DBG: Sending user name")
    session.write((USER_NAME + '\r').encode('ascii'))

index, match_obj, text = session.expect(["Password:".encode('ascii')])
if match_obj:
    print("DBG: Sending password")
    session.write((USER_PW + '\r').encode('ascii'))


print("Checking for failed login")
index, match_obj, text = session.expect(["Login incorrect".encode('ascii')], timeout=3)

if match_obj:
    print("Login failed")
else:
    print("Well, at least we didn't see, 'Login failed'")

To better understand what's going on here, take a look at the telnetlib source code. You'll notice that the expect() method returns three values: the index of where the text was found, the match object and the text read up to that point. I took advantage of previous regex experience that match objects will evaluate to a boolean based on whether a match was found or not. You might want to use some other combinations of the returned values to determine what exactly the expect call found. Again, tedious, but not difficult.

username = input("Enter user name")
password = input("Enter password")

try:
    session.write(str(username).encode('ascii') + b"\r")
    session.write(str(password).encode('ascii') + b"\r")
    ***this is the point where the console will return "Incorrect login"***
except Exception as e:
    print "exception raised"
    pass
else:
    **Rest of the code**
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top