正在学习写的网页代理服务器在对中间数据加密时出现错误,浏览器接收资源不全,
用的 SocketServer 模块,
client中:
python#!/usr/bin/env python2
# conding=utf-8
import sys
import socket
from SocketServer import ThreadingMixIn, TCPServer, StreamRequestHandler
import struct
import select
import logging
from AesEncrypt import AesEncrypt
import hashlib
def encrypt(data):
newencrypt = AesEncrypt()
psw = 'admin'
salt = '123456'
newencrypt.md5(psw,salt)
return newencrypt.encrypt(data)
def decrypt(data):
newdecrypt = AesEncrypt()
psw = 'admin'
salt = '123456'
newdecrypt.md5(psw,salt)
return newdecrypt.decrypt(data)
def sendall(sock,data):
length = 0
while True:
result = sock.send(data[length:])
if result < 0:
return result
length += result
if length == len(data):
return length
class Log():
def __init__(self):
self.logger = logging.getLogger('log')
self.logger.setLevel(logging.DEBUG)
f = logging.FileHandler('./log')
f.setLevel(logging.DEBUG)
self.logger.addHandler(f)
def log(self, data):
self.logger.info(data)
class Server(ThreadingMixIn,TCPServer):pass
class Socks5Server(StreamRequestHandler):
def handleData(self, source, dest):
try:
while 1:
active, w, x= select.select([source, dest], [], [], 5)
if not active:
break
if source in active:
data = source.recv(4096)
if len(data) <= 0:
break
data = encrypt(data)
re = sendall(dest,data)
#re = dest.send(data)
if re < len(data):
raise Exception('Failed to send all data')
if dest in active:
data = dest.recv(4096)
if len(data) <= 0:
break
data = decrypt(data)
re = sendall(source,data)
#re = source.send(data)
if re < len(data):
raise Exception('Failed to send all data')
finally:
self.log.log('closed')
source.close()
dest.close()
def handle(self):
self.log = Log()
socks = self.connection
socks.recv(262)
socks.send("\x05\x00")
data = self.rfile.read(4)
#print data
mode = ord(data[1])
if mode !=1:
logging.warn('mode !=1')
return
addrtypr = ord(data[3])
addr_to_send = data[3]
if addrtypr == 1:
addr_ip = self.rfile.read(4)
addr = socket.inet_ntoa(addr_ip)
addr_to_send += addr_ip
elif addrtypr == 3:
addr_len = self.rfile.read(1)
addr = self.rfile.read(ord(addr_len))
addr_to_send += addr_len +addr
else:
logging.warn('addr_type not support')
return
addr_port = self.rfile.read(2)
addr_to_send += addr_port
port = struct.unpack('>H', addr_port)
reply = "\x05\x00\x00\x01"
reply += socket.inet_aton('0.0.0.0') + struct.pack('>H', 2222)
self.wfile.write(reply)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
sock.connect(('127.0.0.1', 1083))
sock.send(addr_to_send)
self.handleData(socks, sock)
logging.info('connecting %s:%s'%(addr,port[0]))
if __name__=="__main__":
HOST, PORT="localhost", 8088
try:
server = Server((HOST, PORT), Socks5Server)
server.serve_forever()
except KeyboardInterrupt:
server.shutdown()
sys.exit()
server中:
python#!/user/bin/env python2
# conding=utf-8
from AesEncrypt import AesEncrypt
from SocketServer import StreamRequestHandler, ThreadingMixIn, TCPServer
import socket
import struct
from select import select
import logging
import hashlib
def encrypt(data):
newencrypt = AesEncrypt()
psw = 'admin'
salt = '123456'
newencrypt.md5(psw,salt)
return newencrypt.encrypt(data)
def decrypt(data):
newdecrypt = AesEncrypt()
psw = 'admin'
salt = '123456'
newdecrypt.md5(psw,salt)
return newdecrypt.decrypt(data)
def sendall(sock,data):
length = 0
while True:
result = sock.send(data[length:])
if result <0:
return result
length += result
if length == len(data):
return length
class ServerThread(ThreadingMixIn, TCPServer):
pass
class Server(StreamRequestHandler):
def handle(self):
socks = self.connection
addrtype = ord(socks.recv(1))
if addrtype == 1:
addr = socket.inet_ntoa(self.rfile.read(4))
elif addrtype == 3:
addr = self.rfile.read(ord(socks.recv(1)))
else:
logging.warn('addr type not support')
return
port = struct.unpack('>H', self.rfile.read(2))
logging.info('connecting %s:%d'%(addr,port[0]))
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
client.connect((addr, port[0]))
try:
while 1:
active, w, x = select([socks, client], [], [])
if not active:
break
if socks in active:
data = socks.recv(4096)
if len(data)<= 0:
break
data = decrypt(data)
re = sendall(client,data)
#re = client.send(data)
if re < len(data):
raise Exception('Failed to send all data')
if client in active:
data = client.recv(4096)
if len(data) <= 0:
break
data = encrypt(data)
re = sendall(socks,data)
#re = socks.send(data)
#undata = decrypt(data)
if re < len(data):
raise Exception('Failed to send all data')
finally:
print 'closed!!!'
client.close()
socks.close()
if __name__== "__main__":
HOST, PORT="localhost", 1083
server = ServerThread((HOST, PORT), Server)
server.serve_forever()
AesEncrypt.py:
python# coding=utf-8
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import hashlib
class AesEncrypt(object):
def md5(self, psw, salt):
self.hasli = salt + psw
self.MD5 = hashlib.md5(self.hasli).hexdigest()
self.KEY = self.MD5[0:16]
self.IV = self.MD5[16:]
def encrypt(self, data):
length = 16
count = len(data)
if count == 0:
return data
elif count < length:
add = (length - count)
data = data + ('$' * add)
elif count > length:
if count % length == 0:
data = data
else:
add = (length - (count % length))
data = data + ('$' * add)
obj = AES.new(self.KEY, AES.MODE_CBC, self.IV)
cipherdata = obj.encrypt(data)
#cipherdata = b2a_hex(cipherdata)
return cipherdata
def decrypt(self, cipherdata):
if len(cipherdata) == 0:
return cipherdata
else:
obj = AES.new(self.KEY, AES.MODE_CBC, self.IV)
#data = a2b_hex(cipherdata)
data = obj.decrypt(cipherdata)
data = data.rstrip('$')
return data
encrypt()是加密函数,decrypt()解密,用的是AES加密,因为不足16位倍数时需要补位,但解密后会删掉补位的字符。
开始代理后,结果网页加载不全,一般只能打开一部分资源,大部分加载不出来(如不能获取css,js,图片等等,但都是随机会少一些资源。)。
因为对TCP协议不是很了解,用wireshark抓包分析也看不出什么,
比较收到、发出的数据包的md5值也是一样,不知道哪出了问题,新人求指点啊~~~
sockcs.sendall() 也是使用过,有时候会爆出error: [Errno 104] Connection reset by peer
添加回答
举报
0/150
提交
取消