Unable to retrieve cert chain Python - python

I have this code just as a tester for another program that I am trying to write and this does not pull the cert.
import socket, ssl, pprint
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s,
ca_certs="etc/ca_certs_file",
cert_reqs=ssl.CERT_REQUIRED)
ssl_socket.connect (('www.google.com', 443))
pprint.pprint(ssl_sock.getpeercert())
ssl_sock.close()
The code that I have for my other project can not grab the cert chain with the following code..
def get_peer_cert_chain(host, port):
try:
port = int(port)
ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
sock = OpenSSL.SSL.Connection(ctx, socket.socket())
SSLSocket.connect((host, port))
SSLSocket.do_handshake()
SSLSocket.getpeercert(binary_form=False)
return sock.get_peer_cert_chain()
except:
print('INFO: Unable to retrieve certificate chain from ' + str(host) + ':' + str(port))
exit(1)
def cert_chain_interpreter(host, port, chain):
if chain != None:
output_csv = open(args.output,"a")
writer = csv.writer(output_csv)
for cert in chain:
x509Name = OpenSSL.crypto.X509.get_subject(cert)
PKey = OpenSSL.crypto.X509.get_pubkey(cert)
issuer = OpenSSL.crypto.X509.get_issuer(cert)
writer_data = [host, port, OpenSSL.crypto.X509Name.get_components(x509Name), OpenSSL.crypto.X509.has_expired(cert), OpenSSL.crypto.X509.get_notBefore(cert), OpenSSL.crypto.X509.get_notAfter(cert), OpenSSL.crypto.X509Name.get_components(issuer), OpenSSL.crypto.X509.get_signature_algorithm(cert), OpenSSL.crypto.X509.get_serial_number(cert), OpenSSL.crypto.X509.get_version(cert), OpenSSL.crypto.PKey.bits(PKey)]
writer.writerow(writer_data)
output_csv.close()
This code prints out unable to retrieve certificate chain.

Related

proxy server with python

i have an university project with python which i have to write a proxy server that waits for a request from a client and then connects the client to the server. i searched the net and found an already-written code from this site:
https://www.geeksforgeeks.org/creating-a-proxy-webserver-in-python-set-1/
so i used it and made some changes in the code and add the public server and port to it
but when i run it i get this error:
line 33, in main
request = conn.recv(4096)
NameError: name 'conn' is not defined
so i'm not very familiar with sockets and python so if there are obvious mistakes in the code i would be happy if u guys could explain them in a very basic way so my amateur butt would understand it lol
this is the code:
import signal
import socket
import threading
class Proxy:
def __init__(self):
# creating a tcp socket
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# reuse the socket
self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.ip = 'localhost'
self.port = 8080
self.serverSocket.bind((self.ip, self.port))
self.serverSocket.listen(10)
self.__clients = {}
def shutdown(self):
# shutdown on cntrl c
signal.signal(signal.SIGINT, self.shutdown)
def multirequest (self):
while True:
# establish the connection
(clientSocket, client_address) = self.serverSocket.accept()
d = threading.Thread(name=self._getclientname(client_address),
target=self.proxy_thread,
args=(clientSocket, client_address))
d.setDaemon(True)
d.start()
def main(self, conn):
# get the request from browser
request = conn.recv(4096)
# parse the first line
first_line = request.split('\n')[0]
# get url
url = first_line.split(' ')[1]
http_pos = url.find("://")
if http_pos == -1:
temp = url
else:
temp = url[(http_pos + 3):]
webserver = ""
port = -1
port_pos = temp.find(":")
# find end of web server
webserver_pos = temp.find("/")
if webserver_pos == -1:
webserver_pos = len(temp)
if port_pos == -1 or webserver_pos < port_pos:
# default port
port = 80
webserver = temp[:webserver_pos]
else: # specific port
port = int((temp[(port_pos + 1):])[:webserver_pos - port_pos - 1])
webserver = temp[:port_pos]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
s.connect((webserver, port))
s.sendall(request)
while 1:
# receive data from web server
data = s.recv(4096)
if len(data) > 0:
conn.send(data) # send to browser/client
else:
break
p = Proxy()
p.main()
In python, the common pattern for executables is like this:
def main(): # Or whatever name you want to use
"""Your code here"""
# If you are importing the code, the condition will evaluate to false.
if __name__ == "__main__":
main()
Have in mind that you can use whatever function name you want.
You need to put your code inside of a class like this. Any variables you plan to use through your code, define inside of the __init__ method, this could be for example your self.serverSocket, ip, port number, etc.
The init method is deigned to run once, once you create an instance of the class, it usually stores variables. The main method or any other methods you define, would be where you put the rest of your code.
import signal
import socket
import threading
class proxy():
def __init__(self):
# creating a tcp socket
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# reuse the socket
self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.your_ip = "127.0.0.1" # loop back address
self.your_port = 80 # use a port thats open like port 80
def shutdown(self):
# add your signal shutdown code here
pass
def main(self):
# shutdown on cntrl c
signal.signal(signal.SIGINT, self.shutdown)
self.serverSocket.bind((self.your_ip, self.your_port))
self.serverSocket.listen(10)
self.__clients = {}
while True:
# establish the connection
(clientSocket, client_address) = self.serverSocket.accept()
d = threading.Thread(name=self._getClientName(client_address),
target=self.proxy_thread,
args=(clientSocket, client_address))
d.setDaemon(True)
d.start()
# get the request from browser
request = conn.recv(4096)
# parse the first line
first_line = request.split('\n')[0]
# get url
url = first_line.split(' ')[1]
http_pos = url.find("://")
if http_pos == -1:
temp = url
else:
temp = url[(http_pos + 3):]
port_pos = temp.find(":")
# find end of web server
webserver_pos = temp.find("/")
if webserver_pos == -1:
webserver_pos = len(temp)
webserver = ""
port = -1
if port_pos == -1 or webserver_pos < port_pos:
# default port
port = 80
webserver = temp[:webserver_pos]
else: # specific port
port = int((temp[(port_pos + 1):])[:webserver_pos - port_pos - 1])
webserver = temp[:port_pos]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
s.connect((webserver, port))
s.sendall(request)
while 1:
# receive data from web server
data = s.recv(4096)
if len(data) > 0:
conn.send(data) # send to browser/client
else:
break
p = proxy()
p.main()
I successful make a local python proxy via socket module: https://github.com/wayne931121/Python_Proxy_Server/blob/main/Proxy.py
It can run http and https request.
Code:
#!/usr/bin/env python
# coding: utf-8
# In[ ]:
# 參考資料
# https://docs.python.org/3/library/socket.html
# https://stackoverflow.com/questions/24218058/python-https-proxy-tunnelling
# https://stackoverflow.com/questions/68008233/proxy-server-with-python/73851150#73851150
import sys
#import ssl
import time
import signal
import socket
#import certifi
import threading
with open("log.txt", "w") as f:
f.write("")
def signal_handler(sig, frame):
print('Proxy is Stopped.')
sys.exit(0)
def write(*content, prt=False):
if prt :
if len(content[0])<100:
print(*content)
else:
print("This message is too long not print in cmd but will store at log.txt.")
if type(content[0])==bytes:
content = b" ".join(content)
else:
content = bytes(" ".join(content), encoding="utf-8")
with open("log.txt", "ab") as f:
f.write(content+b"\n")
class Proxy:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # creating a tcp socket
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reuse the socket
self.ip = "127.0.0.1"
self.port = 8080
# self.host = socket.gethostbyname(socket.gethostname())+":%s"%self.port
self.sock.bind((self.ip, self.port))
self.sock.listen(10)
print("Proxy Server Is Start, See log.txt get log.")
print("Press Ctrl+C to Stop.")
start_multirequest = threading.Thread(target=self.multirequest)
start_multirequest.setDaemon(True)
start_multirequest.start()
while 1:
time.sleep(0.01)
signal.signal(signal.SIGINT, signal_handler)
def multirequest(self):
while True:
(clientSocket, client_address) = self.sock.accept() # establish the connection
client_process = threading.Thread(target=self.main, args=(clientSocket, client_address))
client_process.setDaemon(True)
client_process.start()
def main(self, client_conn, client_addr): # client_conn is the connection by proxy client like browser.
origin_request = client_conn.recv(4096)
request = origin_request.decode(encoding="utf-8") # get the request from browser
first_line = request.split("\r\n")[0] # parse the first line
url = first_line.split(" ")[1] # get url
http_pos = url.find("://")
if http_pos == -1:
temp = url
else:
temp = url[(http_pos + 3):]
webserver = ""
port = -1
port_pos = temp.find(":")
webserver_pos = temp.find("/") # find end of web server
if webserver_pos == -1:
webserver_pos = len(temp)
if port_pos == -1 or webserver_pos < port_pos: # default port
port = 80
webserver = temp[:webserver_pos]
else: # specific port
port = int(temp[(port_pos + 1):])
webserver = temp[:port_pos]
write("Connected by", str(client_addr))
write("ClientSocket", str(client_conn))
write("Browser Request:")
write(request)
server_conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_conn.settimeout(1000)
try:
server_conn.connect((webserver, port)) # "server_conn" connect to public web server, like www.google.com:443.
except: # socket.gaierror: [Errno 11001] getaddrinfo failed
client_conn.close()
server_conn.close()
return
if port==443:
client_conn.send(b"HTTP/1.1 200 Connection established\r\n\r\n")
client_conn.setblocking(0)
server_conn.setblocking(0)
write("Connection established")
# now = time.time()
client_browser_message = b""
website_server_message = b""
error = ""
while 1:
# if time.time()-now>1: # SET TIMEOUT
# server_conn.close()
# client_conn.close()
# break
try:
reply = client_conn.recv(1024)
if not reply: break
server_conn.send(reply)
client_browser_message += reply
except Exception as e:
pass
# error += str(e)
try:
reply = server_conn.recv(1024)
if not reply: break
client_conn.send(reply)
website_server_message += reply
except Exception as e:
pass
# error += str(e)
write("Client Browser Message:")
write(client_browser_message+b"\n")
write("Website Server Message:")
write(website_server_message+b"\n")
# write("Error:")
# write(error+"\n")
server_conn.shutdown(socket.SHUT_RDWR)
server_conn.close()
client_conn.close()
return
server_conn.sendall(origin_request)
write("Website Host Result:")
while 1:
# receive data from web server
data = server_conn.recv(4096)
try:
write(data.decode(encoding="utf-8"))
except:
write(data)
if len(data) > 0:
client_conn.send(data) # send to browser/client
else:
break
server_conn.shutdown(socket.SHUT_RDWR)
server_conn.close()
client_conn.close()
Proxy()

Using proxy and multiple sockets in python

I'm writing a proxy with tcp connection that listens to multiple ports from a client and forward it to a server.
The problem is that the software hangs on the sock.accept.
Maybe I'm doing a messy logic here, but I need a client that connects to a PC, and that PC connects to another device. So I wrote that small proxy, and I get INVALID ARGUMENT ERROR in socket.accept()
import select
import socket
import threading
class Proxy(object):
def __init__(self, ip, ports):
self._ip = ip
self._sockets = []
self._proxy = {}
for port in ports:
self._proxy[port] = self.add_socket(port)
def add_socket(self, port=None):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if port:
# sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(('0.0.0.0',port))
self._sockets.append(sock)
return sock
def get_client(self, src_sock, src_addr):
src_ip, src_port = src_addr
_, dst_port = src_sock.getsockname()
if src_ip == self._ip:
# got packet from device
dst_addr = ("10.8.8.210", dst_port)
else:
# got packet from client
dst_addr = self._ip, dst_port
print(">", src_port, dst_addr)
dst_sock = self._proxy[src_port]
return dst_sock, dst_addr
def run(self):
while True:
read_list, _, _ = select.select(self._sockets, [], [])
if read_list:
for sock in read_list:
try:
conn, addr = sock.accept()
data = conn.recvfrom(16*2024)
# print("got data from {} {}".format(sock, addr))
dst_sock, dst_addr = self.get_client(sock, addr)
# print("forwarding data from {} to {}".format(addr, dst_addr, len(data)))
dst_sock.sendto(data, dst_addr)
except:
raise # pass # print("no recipient for data")
for s in self._sockets:
s.close()
ports = [30001,30002,30003, 30070, 30071,30072,30075]
p = Proxy("192.168.2.10", ports)
p.run()
You have to call listen on the socket before accept:
adding sock.listen(1) to add_socket after bind
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('0.0.0.0', port))
sock.listen(1)
self._sockets.append(sock)
then allows you to call accept without the error. You may want to set the listen backlog to a greater number.

Unable to get Socket to receive packets

I'm trying to send a message from Client to Server using socket. For some reason, the message is not received. example: the client sends 'myname_0' the server needs to receive it and decode it and continue further.
Listener:
import socket
class SocketSender():
def __init__(self):
self.sock = socket.socket()
ip = socket.gethostname() # IP to server.
port = 7000
self.sock.bind((ip, port))
print("Binding successful.")
self.sock.listen(2)
print("Listening....")
self.listening = True
# self.sock.connect((ip, port))
# print("Connected.")
def sendpacket(self, packet):
self.sock.send(packet.encode())
def receivepacket(self):
while self.listening:
con, addr = self.sock.accept()
print("Receiving packet from " + str(addr))
packet = self.sock.recv(1024).decode("utf-8")
return str(packet)
Sender:
import socket
sock = socket.socket()
ip = socket.gethostname()
port = 7000
sock.connect((ip, port))
print("connection to " + ip)
message = "test_0"
sock.send(message.encode("utf-8"))
When run:
import GUI
import SocketSender
# Entry: 0, Exit: 1
gui = GUI.ASGui()
# gui.run()
socket = SocketSender.SocketSender()
id = input()
while 1 == 1:
packet = socket.receivepacket()
name, state = packet.split("_")
break
if state == 0:
print("Welcome back, " + name)
else:
if state == 1:
print("Goodbye, " + name)
I do get the outputs Listening and Binded. But I am unable to receive a message. Help would be appreciated. Thank you.

Multiclient server in Python - how to broadcast?

I found online a simple multiclient echo server in Python using threads:
#!/usr/bin/env python
import socket
import sys
import threading
class Client(threading.Thread):
def __init__(self, ip, port, connection):
threading.Thread.__init__(self)
self.connection = connection
self.ip = ip
self.port = port
def run(self):
data = self.connection.recv(1024)
if data :
self.connection.sendall(data)
else :
self.connection.close()
class Server:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.address = (self.ip, self.port)
self.server = None
self.clients = []
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(self.address)
except socket.error, e:
if self.server:
self.server.close()
sys.exit(1)
def run(self):
self.open_socket()
self.server.listen(5)
while True :
connection, (ip, port) = self.server.accept()
c = Client(ip, port, connection)
c.start()
self.clients.append(c)
self.server.close()
if __name__ == '__main__':
s = Server('127.0.0.1', 6666)
s.run()
And I wrote a client:
import socket
import sys
port = 6666
size = 1024
s = None
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
s.connect(('127.0.0.1', port))
except socket.error, (value, message):
if s:
s.close()
print "Could not open socket: " + message
sys.exit(1)
data = raw_input('> ')
s.sendall(data)
data = s.recv(size)
print "Server sent: %s " % data
s.close()
Everything works great but I wonder how could I add to the server the functionality of broadcast to be able to echo back the message to all connected clients? Or be able to send a message to a specific client?
I have all clients in server's class, but I do not know how to (and where in the server's code, in Client class or Server class place the code to broadcast and send private messages? Thank you.
EDIT:
New server:
#!/usr/bin/env python
import socket
import sys
import threading
class Client(threading.Thread):
def __init__(self, ip, port, connection):
threading.Thread.__init__(self)
self.connection = connection
self.ip = ip
self.port = port
def run(self):
while True:
data = self.connection.recv(1024)
if data :
self.connection.sendall(data)
else :
break
self.connection.close()
class Server:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.address = (self.ip, self.port)
self.server = None
self.clients = []
def send_to_all_clients(self, msg):
for client in self.clients :
client.connection.send(msg)
def send_to_client(self, ip, port, msg):
for client in self.clients :
if client.ip == ip and client.port == port :
client.connection.send(msg)
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind(self.address)
except socket.error, e:
if self.server:
self.server.close()
sys.exit(1)
def run(self):
self.open_socket()
self.server.listen(5)
while True :
connection, (ip, port) = self.server.accept()
c = Client(ip, port, connection)
c.start()
self.clients.append(c)
self.server.close()
if __name__ == '__main__':
s = Server('127.0.0.1', 6666)
s.run()
New client:
import socket
import sys
port = 6666
size = 1024
s = None
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
s.connect(('127.0.0.1', port))
except socket.error, (value, message):
if s:
s.close()
print "Could not open socket: " + message
sys.exit(1)
while True:
data = raw_input('> ')
s.sendall(data)
data = s.recv(size)
print "Server sent: %s " % data
s.close()
Since you already have a list of clients in your Server , you could use it in a function like that :
def send_to_all_clients(self, msg):
for client in self.clients :
client.connection.send(msg)
Then you can make a function to select a specific client :
def send_to_client(self, ip, port, msg):
for client in self.clients :
if client.ip == ip and client.port == port :
client.connection.send(msg)
Note
It's best to add a Send() method to Client and call it to send the msg instead of using client.connection.send(msg)
You could use those functions in the server's run method , if you modify it to handle events
( you could do that with select.select() , or with user input ( KeyboardInterrupt ) , etc , the design is up to you ) .
Also you should modify both client.py and Client , and make them more persistent , because now they close as soon as they sendall or recv .
I hope this gives you some ideas

python 3.4.3 file is not writing completly

The following is complete client , server and sendproc codes:
Client.py
from socket import *
import pickle
import sendproc
import struct
s = socket(AF_INET, SOCK_STREAM) # Create a socket object
host = "192.168.1.4" # Get local machine name
port = 1094 # Reserve a port for your service.
s.connect((host, port))
with open("file.txt",'rb') as f:
print ('file opened')
print('Sending file...')
for data in f:
print(data)
print("MSG sent")
sendproc.send_msg(s, data)
Server.py
from socket import *
import pickle
import sendproc
port = 1094 # Reserve port for service.
s = socket(AF_INET,SOCK_STREAM) # Create a socket object
host = "192.168.1.4" # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5)
print('server is listening')
conn,addr = s.accept()
with open("file1.txt",'w') as fb:
print("File downloading\n",fb)
while True:
print("hi")
data = sendproc.recv_msg(conn)
print(data)
if not data:
print("No data")
break
fb.write(data)
fb.flush()
print("Download complete\n")
SendRecieveProcedure.py
import struct
def send_msg(s, msg):
msg2 = struct.pack('>I', len(msg)) + msg
s.send(msg2)
def recv_msg(s):
# Read message length and unpack it into an integer
raw_msglen = s.recv(4)
print(raw_msglen)
if not raw_msglen:
return None
n = struct.unpack('>I',raw_msglen)[0]
# Read the message data
data = ' '
while len(data) < n:
packet = s.recv(n - len(data)).decode("cp437")
if not packet:
return None
data += packet
#print("hwllo",data )
return data
output prints correctly to the console, but if I go open up the file it's only writing starting lines.so what is the problem in code

Categories

Resources