Compare commits
1 Commits
backport-1
...
1.1
Author | SHA1 | Date | |
---|---|---|---|
5a92243bcb |
21
cert.pem
Normal file
21
cert.pem
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDfTCCAmWgAwIBAgIUbZA2WZ1Q7ZGmYttO+f6w5tFXZLMwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwazELMAkGA1UEBhMCTk8xETAPBgNVBAgMCE5vcmRsYW5kMQ4wDAYDVQQHDAVC
|
||||||
|
b2TDuDEXMBUGA1UECgwOTm92YSdzIHRlc3QgQ0ExIDAeBgNVBAMMF05vdmEncyB0
|
||||||
|
ZXN0aW5nIENBIENlcnQuMB4XDTI1MDMwNDIyMjMwNFoXDTI2MDMwNDIyMjMwNFow
|
||||||
|
bDELMAkGA1UEBhMCWloxDzANBgNVBAgMBkdsb2JhbDEPMA0GA1UEBwwGR2xvYmFs
|
||||||
|
MSAwHgYDVQQKDBdOb3ZhJ3MgdGVzdCBjZXJ0aWZpY2F0ZTEZMBcGA1UEAwwQTm92
|
||||||
|
YSdzIHRlc3QgY2VydDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANmh
|
||||||
|
gdz5oi+Z1ci0oA1q4NeSeU7b58TkRPvz7g2th4x1OjOhyEA2qG2sOKpjwZ9FB7Ce
|
||||||
|
TPenZ3M3ISq5MQxGJdHB5tzP86d4fbnRldqS3hs+XW+OYvVWcIonHr8OQXsx1qFP
|
||||||
|
2yJGIVRMDcxarFg4ZnIk/M5LsgogrYnhOVhg9mi58tLKp+Q+D10RwDPppi0/e5Ud
|
||||||
|
XM4qrkysY0rA1DwiAgj5MSWwnDCTeUbZDA+znBV5b521VS2XkoVhy49A3lCO2YHc
|
||||||
|
zAdoyLwAUl84lDN5oQPlqkMN2kEDJw2UDxpCFmzdVvMX30uuQY+vpYI0suwrDBye
|
||||||
|
0VxkAwX5qI454SLydE8CAwEAAaMYMBYwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4IBAQCIRzTVzeRxWFmBg2wo1W9QXdVorAALw+xcceypHdrA
|
||||||
|
GYTW7WYLmxXHTSy414p0KFdQ9/CgUpXE0LxwD1gLmWlKEheqlh2T9FPBUK/axZvG
|
||||||
|
00o/YtAaSDHtiC+OcEzPfTFxEpdOoMMBoCpyLBt+0CgfV1BJFRK9Hw7ZOaVQ2eLC
|
||||||
|
nxBypEKf3hv0gtGaKnm+vFYDm4Az3+CojtzJiR07WUsPn5HvbOgH6k7jmKuFiR2w
|
||||||
|
FpPrErVbbLMCZB7+uxfaJyQaEc9DmUf+LDFLbVkM7gk1o249WLjRR5d8MatkwEPN
|
||||||
|
auYdVlrb/CpxTbNzzipFCX+hnFojuFjXp266woplKleW
|
||||||
|
-----END CERTIFICATE-----
|
61
certgen.py
61
certgen.py
@@ -1,61 +0,0 @@
|
|||||||
from cryptography import x509
|
|
||||||
from cryptography.x509.oid import NameOID
|
|
||||||
from cryptography.hazmat.primitives import hashes, serialization
|
|
||||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
|
|
||||||
class AutoCertGen:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def gen_cert(self):
|
|
||||||
# Generate private key
|
|
||||||
private_key = rsa.generate_private_key(
|
|
||||||
public_exponent=65537,
|
|
||||||
key_size=2048,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Define subject and issuer (self-signed)
|
|
||||||
subject = issuer = x509.Name(
|
|
||||||
[
|
|
||||||
x509.NameAttribute(NameOID.COUNTRY_NAME, "ZZ"),
|
|
||||||
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Some province"),
|
|
||||||
x509.NameAttribute(NameOID.LOCALITY_NAME, "Some place"),
|
|
||||||
x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Some org"),
|
|
||||||
x509.NameAttribute(NameOID.COMMON_NAME, "localhost"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create certificate
|
|
||||||
certificate = (
|
|
||||||
x509.CertificateBuilder()
|
|
||||||
.subject_name(subject)
|
|
||||||
.issuer_name(issuer)
|
|
||||||
.public_key(private_key.public_key())
|
|
||||||
.serial_number(x509.random_serial_number())
|
|
||||||
.not_valid_before(datetime.datetime.utcnow())
|
|
||||||
.not_valid_after(
|
|
||||||
datetime.datetime.utcnow() + datetime.timedelta(days=365)
|
|
||||||
) # 1 year validity
|
|
||||||
.add_extension(
|
|
||||||
x509.SubjectAlternativeName([x509.DNSName("localhost")]), critical=False
|
|
||||||
)
|
|
||||||
.sign(private_key, hashes.SHA256())
|
|
||||||
)
|
|
||||||
|
|
||||||
# Save private key
|
|
||||||
with open("key.pem", "wb") as f:
|
|
||||||
f.write(
|
|
||||||
private_key.private_bytes(
|
|
||||||
encoding=serialization.Encoding.PEM,
|
|
||||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
|
||||||
encryption_algorithm=serialization.NoEncryption(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Save certificate
|
|
||||||
with open("cert.pem", "wb") as f:
|
|
||||||
f.write(certificate.public_bytes(serialization.Encoding.PEM))
|
|
||||||
|
|
||||||
print("Self-signed certificate and private key generated for HTTPS server!")
|
|
27
key.pem
Normal file
27
key.pem
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpQIBAAKCAQEA2aGB3PmiL5nVyLSgDWrg15J5TtvnxORE+/PuDa2HjHU6M6HI
|
||||||
|
QDaobaw4qmPBn0UHsJ5M96dnczchKrkxDEYl0cHm3M/zp3h9udGV2pLeGz5db45i
|
||||||
|
9VZwiicevw5BezHWoU/bIkYhVEwNzFqsWDhmciT8zkuyCiCtieE5WGD2aLny0sqn
|
||||||
|
5D4PXRHAM+mmLT97lR1cziquTKxjSsDUPCICCPkxJbCcMJN5RtkMD7OcFXlvnbVV
|
||||||
|
LZeShWHLj0DeUI7ZgdzMB2jIvABSXziUM3mhA+WqQw3aQQMnDZQPGkIWbN1W8xff
|
||||||
|
S65Bj6+lgjSy7CsMHJ7RXGQDBfmojjnhIvJ0TwIDAQABAoIBAACkfu8pl4Z/dEei
|
||||||
|
7OQNQDuytYP7lzwYFnIN/tJwhDlwcSsM27wAzU+Blis+nyg6unKVjRGgH2iSLZlk
|
||||||
|
MZZhMKRlZ6qYPJZufySIz2H1VA2NihYVvAoQZsWppugWgS/9bi5Mv49i2J9YmCPV
|
||||||
|
0rNx+y90F4D+bTilbw28qgAuTRvzCzTYqcOLnBvjfHfhh1gzOADB4zHGjEb4qwWd
|
||||||
|
GCPGs85tzfT2Bez6GTCvzNEf8kmGO8EwynZk20SPkswcMIQhES1S6wC3zOi0C9+Y
|
||||||
|
B4dVnfgtukvsgG+AAtBo8rx6iVIKlGMU3xex9+aZPiJ8O8A/zOJU34IpdDMf7Oha
|
||||||
|
bK44pgUCgYEA9mK6tmSgN6Sqji9r7hWSse+tX6faeIeFSDIo33pre2jNyM1qTBHY
|
||||||
|
VZ54CoGa02PLRclqci0TsRaN5Gh+wLVzLW2NDLMEZFXIELF4vGexGnOWLYrxp4hm
|
||||||
|
uk8rQskoa7/pE7gyjgbYjXqn+wM2ifyc/XXFwTbjbFrj7zPkEdhNmV0CgYEA4h+I
|
||||||
|
MLn+4PvABojLekU8EHVLAjnWbKYie/a0ELYDz+DZiGgtU21q4HgaOI8SSRA/UvFW
|
||||||
|
l1i75NmKALT/d89Bok0THmfWAIIPzbsboRJe8f8uce9ICwdmbYKHCJwmgDyhq4ic
|
||||||
|
UoDzWAuUQa144tcC91Mop5VYa5Ee8TYswIuybZsCgYEA0oQw/D6mFmT/xVUHZvnP
|
||||||
|
yXD8Ncr5hBpm6vTQr4Gt7Ffz3CqHNE/bA+zOrEtouk1+FTavWLbjKGAZBJu0EXv3
|
||||||
|
2UzNQ5iBnCkfNAQvIOuICw3Pt0IMkBSfkXirgfjWLJpgz5SGvYtj5B51AKgSJXxN
|
||||||
|
ttK2EQyQ7LgMIQm5SPYD95ECgYEAlJykpWGYYcUTLzg4guN91lNAOPZKNp35i/9X
|
||||||
|
2KPHXZgpX70YDPycgWpt0T42hk5nT9vNTSrEUmOmj1BllhhgyopdRl54B11zhYKz
|
||||||
|
Zejs/Z74p2jbsGPsrYxbswztQNqYZmQiWRbm17bEeWXJTUyCZooA7iL5Objm3SD9
|
||||||
|
yI4HdoECgYEAzNAa7QJy/bgjuaP8fNx+vfsgMWQ9WT12IXnoiJN4I6mKBrSoJGJ2
|
||||||
|
EeM41K1lRglI70WDHFPVn7AQvLiFgfWRoI0ucT65VUzYHT+m2g4p7wwb4wPLkhoj
|
||||||
|
nMLthqEoO+CMIrdGSUVmOwlQ4SnKn9G9a2R4yAEJzkItsYDWD+/hzTc=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
@@ -1,17 +1,31 @@
|
|||||||
# Using NSCL 1.3
|
# Using NSCL 1.3
|
||||||
|
# Port defenition. What ports to use.
|
||||||
|
# port is the HTTP port, port-https is the HTTPS port
|
||||||
port:8080
|
port:8080
|
||||||
directory:/home/nova/Documents/html
|
|
||||||
host:localhost
|
|
||||||
# DANGER: NEVER EVER TURN THIS ON IN PROD!!!!!!!!!!!!
|
|
||||||
allow-all:1
|
|
||||||
# DANGER!!
|
|
||||||
port-https:8443
|
port-https:8443
|
||||||
|
# Here you choose what directory PyWebServer looks in for files.
|
||||||
|
directory:<Enter directory here>
|
||||||
|
# Host defenition, what hosts you can connect via.
|
||||||
|
# You can use FQDNs, IP-addresses and localhost,
|
||||||
|
# Support for multiple hosts is coming.
|
||||||
|
host:localhost
|
||||||
|
# Ignores the host parameter (except for localhost) and allows everything.
|
||||||
|
# DANGER! For obvious reasons this isn't recommended.
|
||||||
|
allow-all:0
|
||||||
|
# Enables HTTP support. (Only enables/disables the HTTP port.)
|
||||||
http:1
|
http:1
|
||||||
|
# Enables HTTPS support. (Only enables/disables the HTTPS port.)
|
||||||
https:1
|
https:1
|
||||||
allow-localhost:0
|
# Allows the use of localhost to connect.
|
||||||
# for use in libraries
|
# The default is on, this is seperate of the host defenition.
|
||||||
# disable-autocertgen:0
|
allow-localhost:1
|
||||||
|
# If you're using the webserver in a library form,
|
||||||
|
# you can disable the AutoCertGen and never trigger it.
|
||||||
|
disable-autocertgen:0
|
||||||
|
# If you wish to block IP-addresses, this function is coming though.
|
||||||
# block-ip:0.0.0.0,1.1.1.1,2.2.2.2
|
# block-ip:0.0.0.0,1.1.1.1,2.2.2.2
|
||||||
|
# If you wish to block User-Agents, this function is coming though.
|
||||||
# block-ua:(NULL)
|
# block-ua:(NULL)
|
||||||
|
# This function is deprecated, allows a connection with no Host header.
|
||||||
|
# You should NEVER have to enable this! It can pose a risk to security!
|
||||||
# allow-nohost:0
|
# allow-nohost:0
|
||||||
# In libraries you can disable everything you don't need.
|
|
||||||
|
35
pywebsrv.py
35
pywebsrv.py
@@ -28,7 +28,7 @@ import signal
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from certgen import AutoCertGen
|
from autocertgen import AutoCertGen
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print(
|
print(
|
||||||
"WARN: You need the AutoCertGen plugin! Please install it from\n"
|
"WARN: You need the AutoCertGen plugin! Please install it from\n"
|
||||||
@@ -95,6 +95,7 @@ class FileHandler:
|
|||||||
"https",
|
"https",
|
||||||
"port-https",
|
"port-https",
|
||||||
"allow-all",
|
"allow-all",
|
||||||
|
"allow-nohost",
|
||||||
"allow-localhost",
|
"allow-localhost",
|
||||||
"disable-autocertgen",
|
"disable-autocertgen",
|
||||||
]
|
]
|
||||||
@@ -121,6 +122,7 @@ class FileHandler:
|
|||||||
or option == "allow-all"
|
or option == "allow-all"
|
||||||
or option == "allow-localhost"
|
or option == "allow-localhost"
|
||||||
or option == "disable-autocertgen"
|
or option == "disable-autocertgen"
|
||||||
|
or option == "allow-nohost"
|
||||||
):
|
):
|
||||||
return bool(int(value))
|
return bool(int(value))
|
||||||
return value
|
return value
|
||||||
@@ -131,7 +133,10 @@ class FileHandler:
|
|||||||
Generate some self-signed certificates using AutoCertGen
|
Generate some self-signed certificates using AutoCertGen
|
||||||
"""
|
"""
|
||||||
autocert = AutoCertGen()
|
autocert = AutoCertGen()
|
||||||
autocert.gen_cert()
|
pk = autocert.generate_private_key()
|
||||||
|
sub, iss = autocert.generate_issuer_and_subject()
|
||||||
|
cert = autocert.build_cert(pk, iss, sub)
|
||||||
|
autocert.write_cert(pk, cert)
|
||||||
|
|
||||||
|
|
||||||
class RequestParser:
|
class RequestParser:
|
||||||
@@ -234,6 +239,22 @@ class WebServer:
|
|||||||
self.https_socket, server_side=True
|
self.https_socket, server_side=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.http_404_html = (
|
||||||
|
"<html><head><title>HTTP 404 - PyWebServer</title></head>"
|
||||||
|
"<body><center><h1>HTTP 404 - Not Found!</h1><p>Running PyWebServer/1.1</p>"
|
||||||
|
"</center></body></html>"
|
||||||
|
)
|
||||||
|
self.http_403_html = (
|
||||||
|
"<html><head><title>HTTP 403 - PyWebServer</title></head>"
|
||||||
|
"<body><center><h1>HTTP 403 - Forbidden</h1><p>Running PyWebServer/1.1</p>"
|
||||||
|
"</center></body></html>"
|
||||||
|
)
|
||||||
|
self.http_405_html = (
|
||||||
|
"<html><head><title>HTTP 405 - PyWebServer</title></head>"
|
||||||
|
"<body><center><h1>HTTP 404 - Method not allowed</h1><p>Running PyWebServer/1.1</p>"
|
||||||
|
"</center></body></html>"
|
||||||
|
)
|
||||||
|
|
||||||
self.running = True
|
self.running = True
|
||||||
|
|
||||||
def start(self, http, https):
|
def start(self, http, https):
|
||||||
@@ -328,15 +349,15 @@ class WebServer:
|
|||||||
if not all([method, path, version]) or not self.parser.is_method_allowed(
|
if not all([method, path, version]) or not self.parser.is_method_allowed(
|
||||||
method
|
method
|
||||||
):
|
):
|
||||||
return self.build_response(405, "Method Not Allowed")
|
return self.build_response(405, self.http_405_html)
|
||||||
|
|
||||||
file_content = self.file_handler.read_file(path)
|
file_content = self.file_handler.read_file(path)
|
||||||
|
|
||||||
if file_content == 403:
|
if file_content == 403:
|
||||||
print("WARN: Directory traversal attack prevented.") # look ma, security!!
|
print("WARN: Directory traversal attack prevented.") # look ma, security!!
|
||||||
return self.build_response(403, "Forbidden")
|
return self.build_response(403, self.http_403_html)
|
||||||
if file_content == 404:
|
if file_content == 404:
|
||||||
return self.build_response(404, "Not Found")
|
return self.build_response(404, self.http_404_html)
|
||||||
if file_content == 500:
|
if file_content == 500:
|
||||||
return self.build_response(
|
return self.build_response(
|
||||||
500,
|
500,
|
||||||
@@ -375,7 +396,7 @@ class WebServer:
|
|||||||
|
|
||||||
headers = (
|
headers = (
|
||||||
f"HTTP/1.1 {status_code} {status_message}\r\n"
|
f"HTTP/1.1 {status_code} {status_message}\r\n"
|
||||||
f"Server: PyWebServer/1.0\r\n"
|
f"Server: PyWebServer/1.1\r\n"
|
||||||
f"Content-Type: {content_type}\r\n"
|
f"Content-Type: {content_type}\r\n"
|
||||||
f"Content-Length: {len(binary_data)}\r\n"
|
f"Content-Length: {len(binary_data)}\r\n"
|
||||||
f"Connection: close\r\n\r\n" # connection close bcuz im lazy
|
f"Connection: close\r\n\r\n" # connection close bcuz im lazy
|
||||||
@@ -400,7 +421,7 @@ class WebServer:
|
|||||||
|
|
||||||
headers = (
|
headers = (
|
||||||
f"HTTP/1.1 {status_code} {status_message}\r\n"
|
f"HTTP/1.1 {status_code} {status_message}\r\n"
|
||||||
f"Server: PyWebServer/1.0\r\n"
|
f"Server: PyWebServer/1.1\r\n"
|
||||||
f"Content-Length: {len(body)}\r\n"
|
f"Content-Length: {len(body)}\r\n"
|
||||||
f"Connection: close\r\n\r\n"
|
f"Connection: close\r\n\r\n"
|
||||||
).encode()
|
).encode()
|
||||||
|
Reference in New Issue
Block a user