sending a period to end a mail DATA telnet session in python - 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

Related

Cannot send message to Azure IoT Hub to units with ":" in their device id

I am trying to send messages from my machine to a IoT-Hub. I am using the following code:
message = Message('{{"temperature": 20,"humidity": 10}}')
client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
client.send_message(message)
This works when the deviceId in CONNECTION_STRING doesn't have colons in it.
CONNECTION_STRING = "HostName=my-iot-hub.azure-devices.net;DeviceId=E0:DC:A0:73:C6:C3;SharedAccessKey=password"
CONNECTION_STRING = "HostName=my-iot-hub.azure-devices.net;DeviceId=my_device;SharedAccessKey=password"
The first connectionstring doesn't work. The process hangs when trying to send the message - but doesn't give me an error message. The second sends without any problems.
Is there some way to escape the colons?
We confirmed this is a bug with url encoding. In the next release of azure-iot-device (releases higher than 2.3.0), we will be adding a fix.
Thanks.

How to know if an SMS sending is failed or successful?

I' creating a SMS gateway from GSM Modem port. I need to verify if an SMS sending is failed or successful. So I think the ways to check failed or success is to check the message storage called outbox if success and failed to draft.But, if I try to issue AT commands to check storage by index or to print the messages contained in all indexes, it returns nothing.
Response after sending a message:
+CMGS: 170
as I read we can read the message with AT+CMGR command
modem = serial.Serial('COM5', 9600, timeout=0)
modem.write(b'AT+CMGR=170\r')
while True:
print(modem.read(100))
input('Type to see response')
I tried also with the command AT+CMGR="ALL" to print out anything in storage, but, no messages are printed out.
Command AT+CMGS directly sends SMSs without storing them. In its command response
+CMGS: 170
number 170 is just a progressive number counting successful sends (it is incremented up to 255 and the restarts from 0) and it is completely unrelated to SMS memory location in which it is stored.
But fortunately that response is sent by the modem only when the SMS is successfully transmitted, otherwise an ERROR response is returned. What does "sent" mean? Just that is has been successfully delivered to SMS service center. Actual delivery to SMS recipient is usually immediate, but it might also be delayed by network congestion or by recipient unavailability.
Just for completeness, AT+CMGR=<index> and AT+CMGL=ALL can actually show also sent messages, but only for those stored with AT+CMGW before sending them. For example with +CMGL you may have N rows, each one reporting:
+CMGL: <index>,<stat>,...
in which can have the following values:
"REC UNREAD" - new incoming message
"REC READ" - already read incoming message
"STO UNSENT" - stored message not yet sent
"STO SENT" - stored message already sent <-- this one is relevant for you

Why can't i receive twice from the same client

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.

Issues with Python Telnetlib trying to automatize a PDU41001

I am trying to make the Python Telnetlib to work with a PDU41001 switched power bar. I previously tried to interact with the device via putty using telnet and it works fine.
In my code, I'm able to connect to the device successfully as the code raise an exception if I change the IP address or the port, but there doesn't seem to be any output from the device whatsoever. Sending carriage returns doesn't seem to change anything. I'm out of ideas and I have no idea if it is an issue with the device, with the lib or with my code.
Here's the function I'm using to connect to the device. I tried to add delays to test if there was an issue with timing but it doesn't seem to change anything. I'm using VSCode to debug and validate input data from the device.
def connect(self):
"""
Establish a telnet connection with credentials
"""
self.ping_ip_address(self.connection["host"])
self.telnet_socket = telnetlib.Telnet()
self.telnet_socket.open(host=self.connection["host"], port=self.connection["port"])
time.sleep(1)
response = self.telnet_socket.read_until('Login Name: ', timeout=2)
self.telnet_socket.write(self.credentials["user"] + "\r")
time.sleep(1)
response = self.telnet_socket.read_until('Login Password: ', timeout=2)
self.telnet_socket.write(self.credentials["password"] + "\r")
response = self.telnet_socket.read_until('Welcome Administrator!', timeout=TELNET_RESPONSE_TIMEOUT)

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.

Categories

Resources