Why can't i receive twice from the same client - python

Basically i have client, ip = s.accept()
i want to send and receive send and receive, but printing out the second receive returns nothing
I'm connecting through Putty RAW Mode, i tried different programs but nothing worked.
def function(client, ip):
print(Fore.YELLOW + f"Connection from {ip} Established")
client.send("Username: ".encode("utf-8"))
username = client.recv(1024).decode("utf-8")
client.send("Password: ".encode("utf-8"))
password = client.recv(1024).decode("utf-8")
print(username + ":" + password)
I expected it to output "username:password"
but it returns "username:"

You seem to just expect the first recv to get the username and the second recv to get the password by magic or luck. If there's some protocol that allows you tell where the username ends and the password begins, you need to implement it.
Your first call to recv might get just the first letter of the username. Maybe the first call got the username and the second call got a space or newline character between the username and the password and you haven't read the password yet. Who knows?
If there's no way to know where the boundary between the username and password is, there's no way this code can possibly work. If there is some way, what is that way and where is the code that implements it?
Is your code supposed to receive the username before you send the Password: prompt? If so, where's the code to do that? You call recv, but you don't check to see if it's the username. It could just be the first character of the username. It could be more. You need to look at it and see what it is. Do not send the Password: prompt until you've received the entire username. You have to actually implement whatever protocol you are using and the client has to use that same protocol.

Related

Is there a simple way to check if a mail backend is valid in Django without sending a mail?

In my tool the users can provide a mail backend using certain infos on a model and send their mails via the backend which gets created from those values. This all works, but I would love to have a quick check if the provided backend actually will work before using it. Using something like this check_mail_connection doesn't work as this actually returns False even though I entered valid connection parameters.
from django.core.mail import get_connection
class User(models.Model):
...
def get_mail_connection(self, fail_silently=False)
return get_connection(host=self.email_host,
port=self.email_port,
username=self.email_username,
password=self.email_password ... )
def check_mail_connection(self) -> bool:
from socket import error as socket_error
from smtplib import SMTP, SMTPConnectError
smtp = SMTP(host=self.email_host, port=self.email_port)
try:
smtp.connect()
return True
except SMTPConnectError:
return False
except socket_error:
return False
I don't want to send a test mail to confirm, as this can easily get lost or fail on a different part of the system. This feature is for sending out emails from the users mail servers, as I suspect most of my users have a mail server anyways and I basically offer white labeling and similar stuff to them.
You have the following line smtp.connect() in your code that attempts to make a connection. If you look at the documentation for smtplib the signature for this method is:
SMTP.connect(host='localhost', port=0)
Meaning you are trying to connect to localhost with port 25 (standard SMTP port). Of course there is no server listening there and you get a ConnectionRefusedError which you catch and return False. In fact you don't even need to call connect because the documentation states:
If the optional host and port parameters are given, the SMTP
connect() method is called with those parameters during
initialization.
Hence you can simply write:
def check_mail_connection(self) -> bool:
from smtplib import SMTP
try:
smtp = SMTP(host=self.email_host, port=self.email_port)
return True
except OSError:
return False
You can also simply use the open method of the email backend's instance rather than creating the SMTP instance and calling connect yourself:
def check_mail_connection(self) -> bool:
try:
email_backend = self.get_mail_connection()
silent_exception = email_backend.open() is None
email_backend.close()
return not silent_exception
except OSError:
return False
I have a few questions for you and would like for you to answer these questions before we can go further.
What type of OS are you running the server on?
What mail client and tutorial did you follow? Postfix?
Can a user on the server send local mail to another user on the server?
What ports are open and what type of security features do you have installed?
What did your logs say when the email failed?
Are you self hosting/ are you acting as the server admin?
(It's fine if this is your first time. Everyone had a first day.)
SSL and A FQDN isn't too important if your just sending mail out. The system will still work, you just won't be able to receive mail.
(I'm talking from the sense of making sure it at least will send an email. You should at least use SSL as it can be gotten for free.)
If you checked all of these things, there is a part of the mail client that you are using and it probably won't send mail out unless it has approval. There are a lot of variables.
All of these things matter or it wont work.
Sorry meant to make this as a comment. I'm not use to speaking on here.

Is there a way to prevent SMTP Connection Timeout? smtplib, python

I have a script that I need to run indefinitely. The script is set to e-mail me confirmations of certain steps being completed on a daily basis. I am trying to use smtplib for this.
The initial connection is set up so that I will enter my login (written into the script) and a password using getpass at the very initiation of the script. I do not want to leave my password written into the script or even reference by the script say in a config file. Therefore, I want to enter the password at initiation and leave the smtp connection in place.
Re-connecting to the smtp connection as required in the script would defeat the point of being able to step away from the script entirely and leave it running indefinitely.
The example code that I am working with at the moment looks like this:
import smtplib
import getpass
smtpObj = smtplib.SMTP('smtp.gmail.com',587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('myemail#gmail.com',password = getpass.getpass('Enter Password: '))
Then I enter the password and the output is:
(235, b'2.7.0 Accepted')
So this all works fine.
The problem is then that the script needs to pause for anywhere from a few minutes to potentially a few days depending on the time. This is achieved using a while loop with time conditions until a certain time when the send function will be called:
smtpObj.sendmail('myemail#gmail.com','recipient#gmail.com','This is a test')
However, after a period of about 20/30 mins it seems (i.e. if the pause is sufficient). Then the smptObj.sendmail call will fail due to a timeout error.
The specific error is as follows:
SMTPSenderRefused: (451, b'4.4.2 Timeout - closing connection. l22sm2469172wre.52 - gsmtp', 'myemail#gmail.com')
I have so far tried the following:
Instantiating the connection object with the following timeout parameterisation:
smtpObj = smtplib.SMTP('smtp.gmail.com',587,timeout=None)
smtpObj = smtplib.SMTP('smtp.gmail.com',587,timeout=86400)
Neither of these seem to supress the 'timeout' of the connection (i.e. the same problem persists).
I have also tried this solution approach suggested in this post:
How can I hold a SMTP connection open with smtplib and Python?
However, this has not worked either!
I do want to try and avoid the solution where I would have to re-connect each time when I wanted to send the e-mail, because I only want to enter the password for the connection the once manually, rather than writing it into the script either directly or indirectly.
There surely is a way to deal with the timeout issue! If anyone can help here, then please let me know! Though, if you think that the more 'obvious' solution of re-connecting just before the script needs to send an e-mail is the better way to go, then please let me know.
Thank you!...
If you don't want to include sensitive credentials in a script, you should use env vars.
From a terminal shell (outside of python):
$ EXPORT secretVariable=mySecretValue
$ echo $secretVariable
$ mySecretValue
$
So to leverage this in your code...
>>> import os
>>> myPW = os.getenv('secretVariable')
>>> myPW
'mySecretVal'
>>>
By doing this, you don't have to manually type in the password. Beyond that, it's not very practical to attempt to leave an idle SMTP connection open for potentially days at a time, just implement a try/except structure..
import smtplib
import os
def smtp_connect():
# Instantiate a connection object...
password = os.getenv('secretVariable')
smtpObj = smtplib.SMTP('smtp.gmail.com',587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login('myemail#gmail.com',password=password)
return smtpObj
def smtp_operations():
try:
# SMTP lib operations...
smtpObj.sendmail('myemail#gmail.com','recipient#gmail.com','This is a test')
# SMTP lib operations...
except Exception: # replace this with the appropriate SMTPLib exception
# Overwrite the stale connection object with a new one
# Then, re-attempt the smtp_operations() method (now that you have a fresh connection object instantiated).
smtpObj = smtp_connect()
smtp_operations()
smtpObj = smtp_connect()
smtp_operations()
By replacing except Exception with the actual SMTP Exception that gets raised when you have a stale connection, you'll be sure you're not catching exceptions that don't pertain to the connection being stale.
So, using try/except, the script will attempt to preform the SMTP operations. If the connection is stale, it will instantiate a fresh connection object and then attempt to re-execute itself with the fresh connection object.

Python Telnet script

Thanks to Python Library i was able to use their example to telnet to Cisco switches, I am using this for learning purposes, specifically learning python.
However, although all the code seem generally easy to read, I am a bit confused as to the following:
1- why use the if statement below
2- why use the "\n" after the username and password write method
3- why am i not getting the output on my bash terminal when the changes are infact committed and successful
HOST = "172.16.1.76"
user = raw_input("Enter your Telnet username : ")
password = getpass.getpass()
tn = telnetlib.Telnet(HOST)
tn.read_until("Username: ")
tn.write(user + '\n') <----- 2
if password: <----- 1
tn.read_until("Password: ")
tn.write(password + "\n") <------2
tn.write("show run \n")
time.sleep(5)
output = tn.read_all() <----- 3
print output
print "=" * 30
print "Configuration Complete."
I am not sure as to why using the if statement above, typically once you input in the Username, you get the password prompt right afterward. why cant we just type :
tn.read_until("Username: ")
tn.write(user + '\n')
tn.read_until("Password: ")
tn.write(password + "\n")
As for the second point, why use the '\n' after the passwords and username in the write method if we going to hit enter after we add them anyway?
1: the line
password = getpass.getpass()
asks you for you password, if you leave it empty, password will contain the empty string which, in an if statement, is the same as False
the script doesn't know ahead of time if you have a password on your server or not, it simulates knowing by asking you first and if you don't input anything, it assumes it doesn't (otherwise it would get stuck on tn.read_until("Password: ") forever.
2: the '\n' simulates you hitting the return key. when you enter your password, for example 'password<RETURN>' the variable password will not contain a trailing newline (\n), this is why it is manually appended
3: this one i dont know, possibly 5 seconds isn't enough time to wait
After execute
tn = telnetlib.Telnet(HOST)
you have created a telnet channel from your machine to HOST. But you still need to communicate with HOST to push/send your commands and receive the outputs.
To push your commands to HOST, you need to execute tn.write("your_commands_or_input \n"), \n means newline/return, which tells your current commands need to be executed now. After the execution, HOST return the result, which will be caught by your telnet object "tn" and saved in its "local cache", you can search any keywords you expected in this cache by using tn.read_until method, if the expected keyword has been found, read_until will stop(always stop on the 1st found), and you can do anything you need(It's your turn now), else the read_until will keep waiting the output from HOST(Haven't you turn yet). Finally if you want to check all output have been cached, you can execute tn.read_all().
Remember some of the HOST using different login output, i.e Username vs username or Password vs password, you better to use regular expression to match them.
There is a python library on github, specifically for telneting to cisco devices.
pip install git+https://github.com/sergeyzelyukin/cisco-telnet.git
import ciscotelnet
with ciscotelnet.CiscoTelnet(host, verbose = False) as cisco:
if cisco.login(final_mode=CiscoTelnet.MODE_ENABLE, user="john", user_pass="12345678", enable_pass="cisco"):
# if cisco.login(final_mode=CiscoTelnet.MODE_ENABLE, line_pass="abcdef", enable_pass="cisco"):
print cisco.cmd("sh int status | inc Fa0/1")
print cisco.conf(["interface fast0/1", "descr blank", "load-interval 300"])
print cisco.wr()

sending a period to end a mail DATA telnet session in python

im using a telnetlib in python to connect to a simple mail server and send out an email; everything works fine until the very end after i enter the DATA command, you submit the body of your message and in order to submit the email in the server's queue, you need to type a period "." on a new line by itself so my end transaction snippet looks like so
self.tnet.write("\n.\n")
self.tnet.read_until("250")
where self.tnet is my telnet session var and read_until waits for the 250 Ok response saying the email has been sent to the queue of the email server and on its way for delivery; however, i do not get that 250 Ok response back and the connection times out to my 10sec timeout flag and no email is received in my inbox... any ideas? ive also tried
self.tnet.write(raw_input()+"\n")
and ive also tried grabbing the raw socket
self.sock=self.tnet.get_socket()
self.sock.send(".\n")
print self.sock.recv(1024)
no response... :/
ive also tried the return carriage "\r" in combination with "\n" and on it own to no avail
any ideas?
thank you,
~george
you need the <CR><LF> newline-squence try:
self.tnet.write("\r\n.\r\n")
hope that helps

Verifying Authentication to a Telnet Session in Python

I am trying to telnet into a Cisco Switch and run a couple of commands on it. I am able to check if the host doesn't exist, not sure how to check if the username or password is correct. This is what I got so far(This is part of my class)
def login(self):
if self.user_name and self.password:
try:
self.connection=telnetlib.Telnet(self.telnet_host)
try:
self.connection.read_until('sername:',1)
self.connection.write(self.user_name+'\r\n')
self.connection.read_until('assword:',1)
self.connection.write(self.password+'\r\n')
self.connection.read_until(self.prompt,1)
print "Connected"
self.loggedON=True
except EOFError:
print "Authentication to "+ self.telnet_host+" failed.\n"
return
except:
print "Can't connect to "+self.telnet_host+"\n"
return
else:
if not self.user_name:
self.user_name=raw_input("Username: ")
self.login()
else:
self.password=raw_input("Password: ")
self.login()
It will still say it is connected even if the wrong password or username.
You could also try Exscript:
from Exscript.util.start import quickstart
def do_something(conn):
conn.autoinit()
conn.execute('show version')
quickstart('telnet://localhost', do_something)
The quickstart() function asks the user for username and password (use start() if that is not what you want). Login failure (and other errors) are handeled automatically. You may also want to look at Exscript.util.start.
First of all, you shouldn't have a blanket try/except block like that. Catch exceptions more narrowly. Also, as others have commented, you might consider SNMP.
Having said that, if you push ahead with Telnet, you might as well just reuse someone else's code. I found this for example with a simple Google search.

Categories

Resources