2013-05-23 1 views
1

Я пытаюсь запустить сервер SSL, поэтому он может принимать объект JSON и отвечать другими объектами JSON. Однако, прежде чем делать объекты JSON, я решил сделать упрощенную версию, и я столкнулся с этой странной ошибкой с SSL, о которой я ничего не могу найти. Решения по созданию сертификата, похоже, не работали, если я не делаю что-то неправильно. Так вот все, что я сделал:Python openSLL Server Crash on connection - нечетная ошибка в SSL

Python Сервер

import socket 
import re 
import ssl 

# Standard socket stuff: 
host = '' # do we need socket.gethostname() ? 
port = 8080 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sock.bind((host, port)) 
sock.listen(1) # don't queue up any requests 

# Loop forever, listening for requests: 
while True: 
    csock, caddr = sock.accept() 
    connstream = ssl.wrap_socket(csock, 
           server_side=True, 
           certfile="cert.pem", 
           keyfile="cert.pem", 
           ssl_version=ssl.PROTOCOL_SSLv23) 
    print "Connection from: " + `caddr` 

    dataBuf = connstream.recv(4096) # read what is there to read 
    extraData = connstream.recv(4096) #see if there is more 
    while len(extraData) != 0: #if something extra was read 
     dataBuf += extraData 
     extraData = connstream.recv(4096) #check again 



    print '--------' 
    print len(dataBuf), dataBuf 
    # Look in the first line of the request for a move command 
    # A move command should be e.g. 'http://server/move?a=90' 
    match = re.match('GET /move\?a=(\d+)\sHTTP/1', dataBuf) 
    if match: 
     angle = match.group(1) 
     print "ANGLE: " + angle + "\n" 
     connstream.sendall("HTTP/1.0 200 OK\r\n"+ 
          "Content-Type: text/html\r\n"+ 
          "Connection: close\r\n"+ 
          "\r\n"+ 
     """<!DOCTYPE html> 
     <head> 
     <title>Success</title> 
     </head> 
     <body> 
     Boo! 
     </body> 
     </html>\r\n 
     """) 
    else: 
     # If there was no recognised command then return a 404 (page not found) 
     print "Returning 404" 
     connstream.sendall("HTTP/1.0 404 Not Found\r\n") 
    #connstream.shutdown(socket.SHUT_RDWR) 
    connstream.close() 

Генерация ключа и сертификата: Я не уверен, если я делаю что-то неправильно в части «Common Name», как я даю Localhost. LOCALDOMAIN после поста Python SSL example from docs gives "Connection reset by peer" error

openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem 

Как я завершаю поля:

Country Name (2 letter code) [AU]:UK 
State or Province Name (full name) [Some-State]:C 
Locality Name (eg, city) []:C 
Organization Name (eg, company) [Internet Widgits Pty Ltd]:U of C 
Organizational Unit Name (eg, section) []:CL 
Common Name (e.g. server FQDN or YOUR name) []:localhost.localdomain 
Email Address []:unis 

Errors: after going to https://localhost:8080/move?a=77 on a browser (Firefox and Chrome)

Connection from: ('127.0.0.1', 39107) 
Traceback (most recent call last): 
    File "ser.py", line 29, in <module> 
    dataBuf = connstream.recv(44096) # read what is there to read 
    File "/usr/lib/python2.7/ssl.py", line 241, in recv 
    return self.read(buflen) 
    File "/usr/lib/python2.7/ssl.py", line 160, in read 
    return self._sslobj.read(len) 
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca 

Помощь оценили! Благодаря!

пс: Я пытался TLSv1 и PROTOCOL_SSLv23, ту же ошибку ...

/// РАЗВЕЙТЕ:

Я пошел на Firefox и вручную добавить сертификат.

Теперь я получаю:

Connection from: ('127.0.0.1', 39220) 
Traceback (most recent call last): 
    File "ser.py", line 29, in <module> 
    dataBuf = connstream.recv(44096) # read what is there to read 
    File "/usr/lib/python2.7/ssl.py", line 241, in recv 
    return self.read(buflen) 
    File "/usr/lib/python2.7/ssl.py", line 160, in read 
    return self._sslobj.read(len) 
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094419:SSL routines:SSL3_READ_BYTES:tlsv1 alert access denied 

Любые идеи?

// Еще одна попытка:

Я сказал Firefox доверять сертификату и теперь я получаю

Connection from: ('127.0.0.1', 39248) 
Traceback (most recent call last): 
    File "ser.py", line 29, in <module> 
    dataBuf = connstream.recv(44096) # read what is there to read 
    File "/usr/lib/python2.7/ssl.py", line 241, in recv 
    return self.read(buflen) 
    File "/usr/lib/python2.7/ssl.py", line 160, in read 
    return self._sslobj.read(len) 
ssl.SSLError: [Errno 1] _ssl.c:1359: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate 

Поиски для этого дают ничего!

// Развейте:

регенерированного ключи и сертификат с помощью http://devsec.org/info/ssl-cert.html, также поставить как общее имя localhost. Я получаю соединение, но сервер застрял и никогда не отвечает ... Может ли быть какая-то проблема в прочитанной части?

+1

Если вы создаете самозаверяющий сертификат, то «Common Name» (CN) должно точно соответствовать имени хоста в заголовке HTTP «Host:», то есть имя хоста, которое вы используете в URL-адресе, поэтому, если вы используете URL 'https: // localhost: 8080/move? a = 77', тогда CN должен быть' localhost' не 'localhost.localdomain'. – Aya

+0

@Aya ОК, я изменил это, я также гарантировал, что Firefox не удаляет сертификат после проверки. Я получаю соединение, но запрос GET никогда не заканчивается. Любая идея почему? Он просто сидит там и никогда не заканчивается ... – unixsnob

ответ

1

Что касается вопроса Последующие, я подозреваю, что проблема с этим кодом ...

dataBuf = connstream.recv(4096) # read what is there to read 
extraData = connstream.recv(4096) #see if there is more 
while len(extraData) != 0: #if something extra was read 
    dataBuf += extraData 
    extraData = connstream.recv(4096) #check again 

... который будет пытаться читать из сокета, пока он не достигнет EOF.

По умолчанию большинство браузеров будут использовать persistent HTTP connection, что означает, что они не будут закрывать исходящую половину своего сокета после отправки запроса, поэтому EOF не произойдет, и ваш код будет блокироваться на одном из те recv() звонки.

Если вы хотите реализовать соответствующий HTTP-сервер, вам необходимо ознакомиться с the protocol.Вам нужно будет прочитать заголовки HTTP по строкам, обращая внимание на заголовки и Content-Length, и как только вы попадаете в конец заголовков, вы должны только читать до Content-Length байт, если в заголовках запроса содержится Connection: keep-alive ,

Протокол может немного усложниться, поэтому проще всего использовать встроенный HTTP-сервер Python и обернуть сокет. Быстрый Google для python https server дает fairly simple example в качестве первого результата.

+0

Привет, Айя. Это точно так. Мне не нужно какое-либо соответствие, мне просто нужно получить сообщение от расширения, обработать его и ответить строкой JSON, содержащей некоторые сериализованные изображения и метаданные. Так что мой вопрос. Является ли чрезмерным использование уже базовых серверов HTTTP для того, что мне нужно? Или вы скажете, что это оправдано и на самом деле будет быстрее? Я просто не хочу тратить время на чтение в библиотеке и изменение фактического сервера ... Спасибо! – unixsnob

+0

@unixsnob Ну, если вам нужно обрабатывать запросы, созданные Firefox, вам понадобится достаточно совместимый сервер, и гораздо проще использовать существующий сервер «BaseHTTP», чем писать свои собственные. Если вы просто используете HTTP для какого-то пользовательского кода клиент-сервер, тогда вы можете использовать что-то более простое, чем HTTP, - это зависит от прецедента. – Aya