Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL in python3 with HTTPServer

I found here a (apparently-)working HTTPS server for python 2: http://code.activestate.com/recipes/442473-simple-http-server-supporting-ssl-secure-communica/?c=15536

I'm trying to port it in python3 but I have no good results. This is my code:

from socketserver import BaseServer
import string,cgi,time
from os import curdir, sep
from http.server import SimpleHTTPRequestHandler, HTTPServer
import ssl
import os # os. path
import socket

class SecureHTTPServer(HTTPServer):
    def __init__(self, server_address, HandlerClass):
        BaseServer.__init__(self, server_address, HandlerClass)
        ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
        #server.pem's location (containing the server private key and
        #the server certificate).
        fpem = 'certificate1.pem'
        ctx.load_verify_locations(fpem)
        self.socket = ctx.wrap_socket(socket.socket(self.address_family,
                                                        self.socket_type))
        self.server_bind()
        self.server_activate()


class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
    def setup(self):
        self.connection = self.request
        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
    def do_GET(self):
        print('get recieved!');
        self.send_error(404,'File Not Found: %s' % self.path)

def test(HandlerClass = SecureHTTPRequestHandler,
         ServerClass = SecureHTTPServer):
    server_address = ('', 1443) # (address, port)
    httpd = ServerClass(server_address, HandlerClass)
    sa = httpd.socket.getsockname()
    print ("Serving HTTPS on", sa[0], "port", sa[1], "...")
    httpd.serve_forever()


if __name__ == '__main__':
    test()

When I run it I get no errors, but when I connect to localhost:1443 (with https) I get no response and the print('get recieved!'); is't triggered.

like image 715
Antonio Ragagnin Avatar asked Mar 15 '14 20:03

Antonio Ragagnin


People also ask

How do I run https in Python?

Note: If you are using this to serve web traffic, you will need to use '0.0. 0.0' in place of 'localhost' to bind to all interfaces, change the port to 443 (the standard port for HTTPS), and run with superuser privileges in order to have the permission to bind to a well-known port.

What is SSL Create_default_context ()?

Socket creation The helper functions create_default_context() returns a new context with secure default settings. The old wrap_socket() function is deprecated since it is both inefficient and has no support for server name indication (SNI) and hostname matching.

How do you do a SSL handshake in Python?

Do_handshake() Method Of SSLSocket Class In Python The method do_handshake() does the TLS handshaking with the peer. While the TLS handshaking can be done as part of connecting with the peer, it can also be opted for later by calling the do_handshake() explicitly.

Is SSL built in Python?

ssl() support for TLS over sockets is being superseded in Python 2.6 by a new 'ssl' module. This package brings that module to older Python releases, 2.3. 5 and up (it may also work on older versions of 2.3, but we haven't tried it).


2 Answers

From Python 3.7 ssl.wrap_socket is deprecated, use SSLContext.wrap_socket instead:

check: https://docs.python.org/3.7/library/ssl.html#ssl.wrap_socket

from http.server import HTTPServer,SimpleHTTPRequestHandler
import ssl

httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
sslctx = ssl.SSLContext()
sslctx.check_hostname = False # If set to True, only the hostname that matches the certificate will be accepted
sslctx.load_cert_chain(certfile='certificate.pem', keyfile="private.pem")
httpd.socket = sslctx.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()
like image 115
Keijack Avatar answered Oct 05 '22 05:10

Keijack


I found another (simpler) solution here: http://www.piware.de/2011/01/creating-an-https-server-in-python/

This is my working porting to python3:

from http.server import HTTPServer,SimpleHTTPRequestHandler
from socketserver import BaseServer
import ssl

httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='certificate.pem', server_side=True)
httpd.serve_forever()
like image 25
Antonio Ragagnin Avatar answered Oct 05 '22 07:10

Antonio Ragagnin