I am trying to send an email through python using yahoo as my server but when I do I get the error
"ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1125)"
I'm guessing that, as it says, my ssl version doesn't match yahoo's but I cannot find what version yahoo is using anywhere. I am using ssl.OPENSSL_VERSION to identify my version which gives it as "OpenSSL 1.1.1i"
Anyone know how I can fix this? I've included the code below
import smtplib
msg = "Hello!, this is a test email. Goodbye!"
fromadd = '*****#yahoo.com'
toadd = 'email#domain.com'
subject = 'Python Test Email'
username = str('*****#yahoo.com')
password = str('********')
server = smtplib.SMTP_SSL('smtp.mail.yahoo.com', 587)
server.ehlo()
server.login(username, password)
server.sendmail(fromadd, toadd, msg)
server.quit()
and the exact error message:
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1125)
server = smtplib.SMTP_SSL('smtp.mail.yahoo.com', 587)
Port 587 is for plain SMTP, where TLS is initiated by an explicit plain text STARTTLS command (explicit TLS). For this use smtplib.SMTP with starttls().
To use smtplib.SMTP_SSL (implicit TLS, i.e. directly after TCP connect) one should connect to port 465 instead.
Related
I've implemented a SOAP client in python with the zeep library. Some of the endpoints require client-side certificate authentication, thus the need to attach the certificate to the python requests's session.
After googling around, I've come up with:
from zeep import Client
from zeep.transports import Transport
from django.utils import timezone
import requests
......
session = requests.Session()
session.verify = False
session.cert= ('pat_to_cert.pem','path_to_privKey.pem')
transport = Transport(session=session)
....
client = Client(wsdl=wsdl, transport=transport)
send = getattr(service, service_name)
result = send(**data)
Debbugging the TLS handshake, the server issues a Certificate Request, but the client replies with an empty certificate. I've already checked the .pem files with openssl with no errors.
Is it possible that python's requests is not attaching the certificate because it does not recognize the server name? How can I enforce to use this certificate for every request?
In your code, you are setting session.verify = False that's why TLS verification is disabled.
what you need to do is to set:
session.verify = 'path/to/my/certificate.pem'
Also, Alternatively, instead of using session.verify you can use session.cert if you just want to use an TLS client certificate:
session.verify = True
session.cert = ('my_cert', 'my_key')
please check the documentation for more details: https://docs.python-zeep.org/en/master/transport.html
hope this helps
I am finding it impossible to set up an encrypted connection with a RabbitMQ broker using python's pika library on the client side. My starting point was the pika tutorial example here but I cannot make it work. I have proceeded as follows.
(1) The RabbitMQ configuration file was:
listeners.tcp.default = 5672
listeners.ssl.default = 5671
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false
ssl_options.cacertfile = /etc/cert/tms.crt
ssl_options.certfile = /etc/cert/tms.crt
ssl_options.keyfile = /etc/cert/tmsPrivKey.pem
auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
auth_mechanisms.3 = EXTERNAL
(2) The rabbitmq-auth-mechanism-ssl plugin was enabled with the following command:
rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
Successful enabling was confirmed by checking the enable status through: rabbitmq-plugins list.
(3) The correctness of the TLS certificates was verified by using openssl tools as described here.
(4) The client-side program to set up the connection was:
#!/usr/bin/env python
import logging
import pika
import ssl
from pika.credentials import ExternalCredentials
logging.basicConfig(level=logging.INFO)
context = ssl.create_default_context(
cafile="/Xyz/sampleNodeCert/tms.crt")
context.load_cert_chain("/Xyz/sampleNodeCert/node.crt",
"/Xyz/sampleNodeCert/nodePrivKey.pem")
ssl_options = pika.SSLOptions(context, '127.0.0.1')
conn_params = pika.ConnectionParameters(host='127.0.0.1',
port=5671,
ssl_options=ssl_options,
credentials=ExternalCredentials())
with pika.BlockingConnection(conn_params) as conn:
ch = conn.channel()
ch.queue_declare("foobar")
ch.basic_publish("", "foobar", "Hello, world!")
print(ch.basic_get("foobar"))
(5) The client-side program failed with the following error message:
pika.exceptions.ProbableAuthenticationError: ConnectionClosedByBroker: (403) 'ACCESS_REFUSED - Login was refused using authentication mechanism EXTERNAL. For details see the broker logfile.'
(6) The log message in the RabbitMQ broker was:
2019-10-15 20:17:46.028 [info] <0.642.0> accepting AMQP connection <0.642.0> (127.0.0.1:48252 -> 127.0.0.1:5671)
2019-10-15 20:17:46.032 [error] <0.642.0> Error on AMQP connection <0.642.0> (127.0.0.1:48252 -> 127.0.0.1:5671, state: starting):
EXTERNAL login refused: user 'CN=www.node.com,O=Node GmbH,L=NodeTown,ST=NodeProvince,C=DE' - invalid credentials
2019-10-15 20:17:46.043 [info] <0.642.0> closing AMQP connection <0.642.0> (127.0.0.1:48252 -> 127.0.0.1:5671)
(7) The environment in which this test was done is Ubuntu 18.04 using RabbitMQ 3.7.17 on Erlang 22.0.7. On the client side, python3 version 3.6.8 was used.
Questions: Does anyone have any idea as to why my test fails? Where can I find a complete working example of setting up an encrypted connection to RabbitMQ using pika?
NB: I am familiar with this post but none of the tips in the post helped me.
After studying the link provided above by Luke Bakken, I am now in a position to answer my own question. The main change with respect to my original example is that I configure the RabbitMQ broker with a passwordless user which has the same name as the CN field of the TLS certificate on both the server and the client side. To illustrate, below, I go through my example again in detail:
(1) The RabbitMQ configuration file is:
listeners.tcp.default = 5672
listeners.ssl.default = 5671
ssl_cert_login_from = common_name
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true
ssl_options.cacertfile = /etc/cert/tms.crt
ssl_options.certfile = /etc/cert/tms.crt
ssl_options.keyfile = /etc/cert/tmsPrivKey.pem
auth_mechanisms.1 = EXTERNAL
auth_mechanisms.2 = PLAIN
auth_mechanisms.3 = AMQPLAIN
Note that, with the ssl_cert_login_from configuration option, I am asking for the username of the RabbitMQ account to be taken from the "common name" (CN) field of the TLS certificate.
(2) The rabbitmq-auth-mechanism-ssl plugin is enabled with the following command:
rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
Successful enabling can be confirmed by checking the enable status through command: rabbitmq-plugins list.
(3) The signed TLS certificate must have the issuer and subject CN fields equal to each other and equal to the hostname of the RabbitMQ broker node. In my case, inspection of the RabbitMQ log file (in /var/log/rabbitmq) shows that the broker is running on a node called: rabbit#pnp-vm2. The host name is therefore pnp-vm2. In order to check the CN fields of the client-side certificate, I use the following command:
ap#pnp-vm2:openssl x509 -noout -text -in /etc/cert/node.crt | fgrep CN
Issuer: C = CH, ST = CH, L = Location, O = Organization GmbH, CN = pnp-vm2
Subject: C = DE, ST = NodeProvince, L = NodeTown, O = Node GmbH, CN = pnp-vm2
As you can see, both the Issuer CN field and the Subject CN Field are equal to: "pnp-vm2" (which is the hostname of the RabbitMQ broker, see above). I tried using this name for only one of the two CN fields but then the connection to the broker could not be established. In my test environment, it was easy to create a client certificate with identical CN names but, in an operational environment, this may be a lot harder to do. Also, I do not quite understand the reason for this constraint: is it a bug or it is a feature? And does it originate in the particular RabbitMQ library I am using (python's pika) or in the AMQP protocol? These question probably deserve a dedicated post.
(4) The client-side program to set up the connection is:
#!/usr/bin/env python
import logging
import pika
import ssl
from pika.credentials import ExternalCredentials
logging.basicConfig(level=logging.INFO)
context = ssl.create_default_context(cafile="/home/ap/RocheTe/cert/sampleNodeCert/tms.crt")
context.load_cert_chain("/home/ap/RocheTe/cert/sampleNodeCert/node.crt",
"/home/ap/RocheTe/cert/sampleNodeCert/nodePrivKey.pem")
ssl_options = pika.SSLOptions(context, 'pnp-vm2')
conn_params = pika.ConnectionParameters(host='a.b.c.d',
port=5671,
ssl_options=ssl_options,
credentials=ExternalCredentials(),
heartbeat=0)
with pika.BlockingConnection(conn_params) as conn:
ch = conn.channel()
ch.queue_declare("foobar")
ch.basic_publish("", "foobar", "Hello, world!")
print(ch.basic_get("foobar"))
input("Press Enter to continue...")
Here, "a.b.c.d" is the IP address of the machine on which the RabbitMQ broker is running.
(5) The environment in which this test was done is Ubuntu 18.04 using RabbitMQ 3.7.17 on Erlang 22.0.7. On the client side, python3 version 3.6.8 was used.
One final word of warning: with this configuration, I was able to establish a secure connection to the RabbitMQ Broker but, for reasons which I still do not understand, it became impossible to start the RabbitMQ Web Management Tool...
I'm having an error with gmail gem while trying to send a mail, this is working fine on local, and was working fine on heroku, but now im moving this app to a VPS server. This is the error:
e = g.compose do
to 'test#gmail.com'
subject 'testasea'
body 'test'
end
=> #<Mail::Message:25450040, Multipart: false, Headers: <From: .......>
e.deliver!
=> OpenSSL::SSL::SSLError: hostname does not match the server certificate
I've added this into an initializer file, without any luck:
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => true,
:openssl_verify_mode => 'none' # I've tested with 0 and false,
}
I tried to monkey path the class
OpenSSL::SSL::SSLSocket.class_eval do
def post_connection_check(hostname)
return true
end
end
with no luck, when I do that i receive a 535 Incorrect authentication data, however I know data is ok because i can do
g.inbox.count :read
And it returns me the right number.
I would like to know:
the incorrect certificate is the one my server (smtp client) is sending? or the one that is received by gmail smtp server?
why it works in local?
Why if i monkey path the class I received an authentication error?
Is there any workaround? i dont care if is not safe, is just a tenting application,.
This is only a guess, but if you are in a WHM VPS there is a function that restricts outgoing SMTP connections, you can find it in Tweak Settings.
Restrict outgoing SMTP to root, exim, and mailman (FKA SMTP Tweak)
It redirects all SMTP connections, If this is enabled you will receive your server self-signed ssl certificate, and if you bypass it using the monkey patch or setting configuration to dont check ssl certificate you will probably found an authentication error as you are in fact connecting to the LOCAL SMTP server.
Just disable it and test again.
I'm trying to connect to a site, e.g www.yahoo.com via proxy using python requests library. So, I define proxy settings as:
HOST = 'host'
PORT = 1234 # random port I have used here
USER = 'user'
PASS = 'password'
PROXY = "%s:%s#%s:%d" % (USER, PASS, HOST, PORT)
PROXY_DICT = {
"http" : 'http://' + PROXY,
"https" : 'https://' + PROXY,
}
I use the following line of code:
requests.get('http://www.yahoo.com', proxies=proxy_dict)
This doesn't raise an exception but the response text is an error page from the proxy saying "Ensure you have installed the certificate". I have a certificate "certificate.crt", which runs fine when used with chrome browser. And the certificate is self-signed. I have tried a couple of things which raise errors.
When used the crt file as a verify param, following error:
SSLError: [Errno bad ca_certs: 'certificate.crt'] []
When used the crt file as a cert param, following error:
Error: [('PEM routines', 'PEM_read_bio', 'no start line'), ('SSL routines', 'SSL_CTX_use_certificate_file', 'PEM lib')]
I managed to get a .pem file(I'm not sure but, it might have been generated using a key and a crt file) as well. When using it with cert param, it doesn't throw error, but the response text is again having the text "...Ensure that the certificate is installed..."
When used .pem file with verify param, following error:
SSLError: [Errno bad handshake] [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]
Now when I refer to requests docs, I see I can use two parameters verify and cert. What shall I use here? And how?
I'm trting to send a simple mail script in PHP. It doesn't work and I have no error in mail log or error log.
Here's my php.ini config
SMTP = relais.videotron.ca
smtp_port = 25
sendmail_from = xxxx#xxxx.com (Of cours it's my ISP email there :D)
sendmail_path = /usr/sbin/sendmail -i -t
and my simple mail() test
mail("xxxx#xxxx.com","test","test");
Nothing's work. What could it be?
The built-in PHP mail command doesn't allow you to authenticate to an SMTP server. Your ISP SMTP server requires authentication and so is refusing the connection.
The info provided by your ISP confirms this;
SMTP server is accessible from an external network by using clear text
authentication using your code "VL" or alias for your mail Example:
customer#videotron.ca
Your options are either use an SMTP server that allows anonymous connections or (as Eamorr says) use a mailer class.
I use SwiftMailer:
require_once('../lib/swiftMailer/lib/swift_required.php');
...
function sendEmail(){
//Sendmail
$transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
//Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
$body="Dear $fname,\n\nYour job application was successful. \n\nYours,\n\nEamorr\n\n\n\n\n\n\n";
//Create a message
$message = Swift_Message::newInstance('Subject goes here')
->setFrom(array($email => "no-reply#yourdomain.com"))
->setTo(array($email => "$fname $lname"))
->setBody($body);
//Send the message
$result = $mailer->send($message);
}
You can send both plaintext and html email with ease.