Jump to content
Zoli1972

AutoIt proxy-server

Recommended Posts

Zoli1972

Hi,

I am a newbie into doing TCP stuff on AutoIt, so I'm looking for some help to code a little proxy server. It should interact with another local pc's browser. The proxy should forward 1:1 all packets sent by the browser to the internet and receive and forward the reply 1:1 back to the pc that sent the request.

How can this be done in AutoIt?

Zoli

Share this post


Link to post
Share on other sites
jvanegmond

Well, I am a bit unsure on this. Because, if the browser sends you the data, then how will you know where to send the data to? :shocked:

Share this post


Link to post
Share on other sites
BrettF

Well, I am a bit unsure on this. Because, if the browser sends you the data, then how will you know where to send the data to? :shocked:

What if you intercept the output data? Is that even possible?

Edited by bert

Share this post


Link to post
Share on other sites
Jos

Well, I am a bit unsure on this. Because, if the browser sends you the data, then how will you know where to send the data to? :shocked:

Thats not that difficult.

Lets say you want to open www.autoit.com on port 80, but instead of using the resolved IPAddress from the DNS you sent that request to the ProxyServer.

This proxyserver will receive the request and then open a TCP session with www.autoit.com and forward the package. Any returned info is sent back to the original requester. This is the basic Proxy "Purpose-in-Live".

I am only lost why you would ever want ot do this with AutoIt3 ?

Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
jvanegmond

It's a start.. :shocked:

TCPStartup()

$Return = RequestGET("www.autoitscript.com", "GET / HTTP/1.0" & @CRLF & @CRLF)

MsgBox(0, "Test Box", "@error = " & @error & @LF & @LF & "$sData = " & $Return)



Func RequestGET($sURL,$sPacket)
    Local $sSocket, $sIP
    
    $sIP = TCPNameToIP($sURL)
    If @error Then
        SetError(1) ;host not found
        Return 0
    EndIf
    
    $sSocket = TCPConnect($sIP,80)
    If @error Then
        SetError(2) ;unable to connect
        Return 0
    EndIf
    
    TCPSend($sSocket,$sPacket)
    
    Local $sData = ''
    While 1
        $sData &= TCPRecv($sSocket,1024)
        If @error Then ExitLoop
    WEnd
    
    Return $sData
EndFunc

Edit: By the way, when most people are looking for code, they are actually looking! Not just asking others to look for them.

Edited by Manadar

Share this post


Link to post
Share on other sites
RogFleming

Hi,

I am a newbie into doing TCP stuff on AutoIt, so I'm looking for some help to code a little proxy server. It should interact with another local pc's browser. The proxy should forward 1:1 all packets sent by the browser to the internet and receive and forward the reply 1:1 back to the pc that sent the request.

How can this be done in AutoIt?

Zoli

I worked a little on your Proxy server, I just wanted to see if it would work

#include <GUIConstantsEx.au3>

Opt('MustDeclareVars', 1)

;==============================================
;==============================================
;Change Internet Explorer Proxy to point to the 
;local machine IP address and port 8080
;==============================================
;==============================================

Example()

Func Example()

    Local $szIPADDRESS = @IPAddress1
    Local $nPORT = 8080
    Local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
    Local $msg, $recv, $urlname, $siteconn, $datareturn, $sentdata, $ipaddr, $sData, $Return

    ; Start The TCP Services
    ;==============================================
    TCPStartup()

    ; Create a Listening "SOCKET".
    ;   Using your IP Address and Port 33891.
    ;==============================================
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)

    ; If the Socket creation fails, exit.
    If $MainSocket = -1 Then Exit


    ; Create a GUI for messages
    ;==============================================
    $GOOEY = GUICreate("My Server (IP: " & $szIPADDRESS & ")", 300, 200)
    $edit = GUICtrlCreateEdit("", 10, 10, 280, 180)
    GUISetState()


    ; Initialize a variable to represent a connection
    ;==============================================
    $ConnectedSocket = -1


    ;Wait for and Accept a connection
    ;==============================================
    Do
        $ConnectedSocket = TCPAccept($MainSocket)
    Until $ConnectedSocket <> -1


    ; Get IP of client connecting
    $szIP_Accepted = SocketToIP($ConnectedSocket)

    ; GUI Message Loop
    ;==============================================
    While 1
        $msg = GUIGetMsg()

        ; GUI Closed
        ;--------------------
        If $msg = $GUI_EVENT_CLOSE Then ExitLoop

        ; Try to receive (up to) 2048 bytes
        ;----------------------------------------------------------------
        $recv = TCPRecv($ConnectedSocket, 2048)

        ; If the receive failed with @error then the socket has disconnected
        ;----------------------------------------------------------------
        If @error Then ExitLoop

        ; Update the edit control with what we have received
        ;----------------------------------------------------------------
        If $recv <> "" Then 
        GUICtrlSetData($edit, $recv & @CRLF & GUICtrlRead($edit))
        $urlname = StringSplit($recv,"/")
        $Return = RequestGET($urlname[3],"GET / HTTP/1.0" & @CRLF & @CRLF)
        GUICtrlSetData($edit, $Return & @CRLF & GUICtrlRead($edit))
        
        TCPSend($ConnectedSocket, $Return)                                  
        EndIf       
    WEnd


    If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)

    TCPShutdown()
EndFunc   ;==>Example

Func RequestGET($sURL,$sPacket)
    Local $sSocket, $sIP
    
    $sIP = TCPNameToIP($sURL)
    If @error Then
        SetError(1) ;host not found
        Return 0
    EndIf
    
    $sSocket = TCPConnect($sIP,80)
    If @error Then
        SetError(2) ;unable to connect
        Return 0
    EndIf
    
    TCPSend($sSocket,$sPacket)
    
    Local $sData = ''
    While 1
        $sData &= TCPRecv($sSocket,1024)
        If @error Then ExitLoop
    WEnd
    
    Return $sData
EndFunc
; Function to return IP Address from a connected socket.
;----------------------------------------------------------------------
Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf

    $sockaddr = 0

    Return $aRet
EndFunc   ;==>SocketToIP

It has more work like redirect and so, but the basic concept works,

need to loop the connection to allow more connections as well.

Share this post


Link to post
Share on other sites
Xand3r

here you go :D autoit proxy :D

tested it and works great (very slow on downloads but it works)

TCPStartup()
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GUIEdit.au3>
Opt("OnExitFunc" , "quit")
Opt("GUIOnEventMode" , 1)
Opt("TrayIconDebug" , 1)
Global $DO_DEBUG=0
#region - GUI Create
GUICreate('',800,600)

$DEBUG=GUICtrlCreateEdit("" , 0 , 0 , 800 , 600,BitOr($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUICtrlSetLimit(-1 , 2000000000000000)
GUISetOnEvent($GUI_EVENT_CLOSE,"quit")
GUISetState()


$socket=TCPListen(@IPAddress1,8080)
If @error Then Exit MsgBox(16 , "Error" , "Could not bind")
While True
    $sock=TCPAccept($socket)
    If $sock<>-1 Then
        If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , "] Client Connected"&@CRLF)
        $recv=""
        While True
            $recv=TCPRecv($sock,4096)
            $error=@error
            If $recv<>"" Then
                If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , StringReplace($recv,@CRLF,@CRLF&">> "&@TAB)&@CRLF)   
                $forward=_Get_Address($recv)
                If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , "] Host Address : " & $forward&@CRLF)
                If $forward="0" Then
                    _Send_Response($sock,400)
                Else
                    $ss=TCPConnect(TCPNameToIP($forward),80)
                    If $ss<>-1 Then
                        _GUICtrlEdit_AppendText($DEBUG , "] Connected to : " & $forward & @CRLF)
                        TCPSend($ss , $recv)
                        $timeout=TimerInit()
                        $data=Binary("")
                        Do
                            $error=0
                            $zdata=TCPRecv($ss,400000,1)
                            If @error Then $error=@error
                            If $zdata<>Binary("") Then 
                                $timeout=TimerInit(); got data reset timeout timer
                                TCPSend($sock,$zdata)
                            EndIf
                        Until $error Or TimerDiff($timeout)>5000; data full or socket closed or timeout reached
                        
                        TCPCloseSocket($ss)
                        TCPCloseSocket($sock)
                    Else
                        _GUICtrlEdit_AppendText($DEBUG , "] Failed to connect to    : " & $forward&@CRLF)
                        _Send_Response($sock,404)
                    EndIf
                    $error=True
                EndIf
            EndIf
            If $error Then
                If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , @CRLF&"] Client disconnected"&@CRLF)
                ExitLoop
            EndIf
        WEnd
    EndIf
    Sleep(10)
WEnd
Func _Get_Address($text)
    $ss=StringSplit($text , @CRLF,1)
    For $i=1 To $ss[0]
        If StringLeft($ss[$i],6)="Host: " Then
            Return StringTrimLeft($ss[$i],6)
        EndIf
    Next
    Return 0        
EndFunc

Func _Send_Response($sock,$code,$data="")
    If $data="" Then
        $data=@CRLF & @CRLF 
    Else
        $data=@CRLF & $data & @CRLF & @CRLF 
    EndIf
    TCPSend($sock , "HTTP/1.0 " & $code & " Message" & $data)
EndFunc

Func quit()
    TCPShutdown()
    Exit
EndFunc
Edited by Xand3r

Only two things are infinite, the universe and human stupidity, and i'm not sure about the former -Alber EinsteinPractice makes perfect! but nobody's perfect so why practice at all?http://forum.ambrozie.ro

Share this post


Link to post
Share on other sites
RogFleming

I added some value to the Proxy server to allow for URL filtering.

TCPStartup()
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GUIEdit.au3>
#include <Array.au3>

Opt("OnExitFunc" , "quit")
Opt("GUIOnEventMode" , 1)
Opt("TrayIconDebug" , 1)

Global $DO_DEBUG=0, $forward, $ss, $sock, $socket

#region - GUI Create
;creates GUI console for the proxy server
GUICreate('',800,600)
;creates reporting area within the GUI window 
$DEBUG=GUICtrlCreateEdit("" , 0 , 0 , 800 , 600,BitOr($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUICtrlSetLimit(-1 , 2000000000000000)
GUISetOnEvent($GUI_EVENT_CLOSE,"quit")
GUISetState()

;opens up the server port to listen on port 8080
$socket=TCPListen(@IPAddress1,8080)
If @error Then Exit MsgBox(16 , "Error" , "Could not bind")
;creates a loop
While True
    ;accept incoming connections from http clients
    $sock=TCPAccept($socket)
    If $sock<>-1 Then
        If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , "] Client Connected"&@CRLF)
        $recv=""
        ;second loop to recv requests from http client
        While True
            $recv=TCPRecv($sock,4096)
            $error=@error
            If $recv<>"" Then
                If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , StringReplace($recv,@CRLF,@CRLF&">> "&@TAB)&@CRLF)   
                $forward=_Get_Address($recv)
                ;insert here logic to check access based on url name
                _SiteApproval($forward)
                If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , "] Host Address : " & $forward&@CRLF)
                If $forward="0" Then
                    _Send_Response($sock,400)
                Else
                    ;connect remote server with requested url from client
                    $ss=TCPConnect(TCPNameToIP($forward),80)
                    If $ss<>-1 Then
                        ;write record in console log 
                        _GUICtrlEdit_AppendText($DEBUG , "] Connected to : " & $forward & @CRLF)
                        ;send data from the requesting client to website
                        TCPSend($ss , $recv)
                        $timeout=TimerInit()
                        $data=Binary("")
                        Do
                            $error=0
                            $zdata=TCPRecv($ss,400000,1)
                            If @error Then $error=@error
                            If $zdata<>Binary("") Then 
                                $timeout=TimerInit(); got data reset timeout timer
                                ;send the recieved data to requesting client
                                TCPSend($sock,$zdata)
                            EndIf
                        Until $error Or TimerDiff($timeout)>5000; data full or socket closed or timeout reached
                        
                        TCPCloseSocket($ss)
                        TCPCloseSocket($sock)
                    Else
                        _GUICtrlEdit_AppendText($DEBUG , "] Failed to connect to    : " & $forward&@CRLF)
                        _Send_Response($sock,404)
                    EndIf
                    $error=True
                EndIf
            EndIf
            If $error Then
                If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , @CRLF&"] Client disconnected"&@CRLF)
                ExitLoop
            EndIf
        WEnd
    EndIf
    Sleep(10)
WEnd


;get the ip address of the requested url
Func _Get_Address($text)
    $ss=StringSplit($text , @CRLF,1)
    For $i=1 To $ss[0]
        If StringLeft($ss[$i],6)="Host: " Then
            Return StringTrimLeft($ss[$i],6)
        EndIf
    Next
    Return 0        
EndFunc

;sending data back to requesting client
Func _Send_Response($sock,$code,$data="")
    If $data="" Then
        $data=@CRLF & @CRLF 
    Else
        $data=@CRLF & $data & @CRLF & @CRLF 
    EndIf
    TCPSend($sock , "HTTP/1.1 " & $code & " Message" & $data)
EndFunc
Func _SiteApproval($forward);add sites and increase index count
    Local $urlArray[6] = [ _
    "www.msn.com", _
    "www.abcnews.com", _
    "www.nfl.com", _
    "www.facebook.com", _
    "www.twitter.com", _
    "www.playboy.com"]
    $iIndex = _ArraySearch($urlArray, $forward, 0, 0, 0, 1)
    ;MsgBox(1,"Results",$iIndex)
    ;Exit   
    If $iIndex > 0 Then
    If $DO_DEBUG Then _GUICtrlEdit_AppendText($DEBUG , "] Access is not allowed for : " & $forward&@CRLF)
    TCPSend($sock , "HTTP/1.1 " & "403")
    TCPCloseSocket($sock)
    EndIf
EndFunc
;quit program
Func quit()
    TCPShutdown()
    Exit
EndFunc

Share this post


Link to post
Share on other sites
RogFleming

I working to make it faster... not sure why it's so slow. also in real testing when more than one machine is connected, the previous session is frozen?????????

Share this post


Link to post
Share on other sites
EnrMa

Hello,

I know this topic is old but I have another working version of a Proxyserver in AutoIT.

It's not perfect written but it works perfect and fast.

I started implementing HTTPS but isn't finished yet.

TCPStartup()
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GUIEdit.au3>
#Include <Array.au3>
#Include <File.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode" , 1)
Opt("TrayAutoPause",0)
Opt("TrayMenuMode",3)
Opt("TrayOnEventMode",1)

Global $ini = @ScriptDir & "\config.ini" 
Global $mainarray[51][10]
Global $proxysocket , $proxysocketssl
Global $GUISHOW = 1

$mainarray[0][0] = "Hostport"
$mainarray[0][1] = "Clientsocket"
$mainarray[0][2] = "Hostsocket"
$mainarray[0][3] = "Request"
$mainarray[0][4] = "Hostname"
$mainarray[0][5] = "Timerhandle Hostconnection"
$mainarray[0][6] = "Blocked"
$mainarray[0][7] = "State"
$mainarray[0][8] = "connection type"


Global $gui = GUICreate("ProxyServer v0.2",700,700)
$DEBUG=GUICtrlCreateEdit("" , 5 , 30 , 500 ,670,BitOr($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUICtrlSetLimit(-1 , 2000000000000000)
Global $button_debug_clear = GUICtrlCreateButton("Clear",5,5,90,20)
GUICtrlSetOnEvent($button_debug_clear,"_debug_clear")
GUICtrlCreateLabel("Listening IP:",515,40,70,20)
GUICtrlCreateLabel("Port HTTP:",515,60,70,20)
GUICtrlCreateLabel("Port HTTPS:",515,80,70,20)
Global $input_proxyip =  GUICtrlCreateInput("",590, 40,100,20)
Global $input_proxyport = GUICtrlCreateInput("",590,60,60,20)
Global $input_proxyportssl = GUICtrlCreateInput("",590,80,60,20)
Global $button_proxy_save = GUICtrlCreateButton("Save and Restart",515,140,180,20)
GUICtrlSetOnEvent($button_proxy_save,"_mainsocket_save")
Global $checkbox_debug = GUICtrlCreateCheckbox("Debugmode", 515 , 240, 120, 20)
Global $checkbox_debug_save = GUICtrlCreateCheckbox("Save Debug to file", 515 , 260, 120, 20)
Global $checkbox_debug_content = GUICtrlCreateCheckbox("Show traffic content", 515 , 280, 120, 20)
Global $button_debug_content = GUICtrlCreateButton("Binary to String",515,320,120,19)
GUICtrlSetOnEvent($button_debug_content,"_debug_binary")
Global $button_debug_array = GUICtrlCreateButton("show mainarray",515,340,120,19)
GUICtrlSetOnEvent(-1,"_show_array")


Global $tray_showgui = TrayCreateItem("Show gui")
TrayItemSetOnEvent($tray_showgui,"_gui_show")

GUISetOnEvent($GUI_EVENT_CLOSE,"_quit")
GUISetState(@SW_SHOW,$gui)

_mainsocket_create()

While 1

    $newclientsock  = TCPAccept($proxysocket)
    If $newclientsock <> -1 Then
        _save("] new HTTP clientconnection :" &_SocketToIP($newclientsock) &@CRLF) 
        _clientconnection_to_mainarray($newclientsock,80,"HTTP")
    EndIf
    $newclientsockssl   = TCPAccept($proxysocketssl)
    If $newclientsockssl <> -1 Then
        _save("] new HTTPS clientconnection :" &_SocketToIP($newclientsockssl) &@CRLF) 
        _clientconnection_to_mainarray($newclientsockssl,443,"HTTPS")
    EndIf

    ;--Recieving Req from Client
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] <> "" Then
            $request = TCPRecv($mainarray[$i][1],4096)
            If @error Then 
                _mainarray_deleteclient($i)
                _save("] Client " & $i & " closed connection" & @CRLF)
            EndIf
            If $request <> "" Then
                _save("] Client " & $i & " requested" & @CRLF & $request)
                $mainarray[$i][3] = $request
                If GUICtrlRead($checkbox_debug_content) = 1 Then _save($request & @CRLF)
            EndIf   
        EndIf
    Next
    ;--connecting and sending Req to Host
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][3] <> "" Then
            If $mainarray[$i][2] = "" Then
                $forward = _Get_Address($mainarray[$i][3])
                _save("]" & $i &" Got Host Address : " & $forward & @CRLF)          
                $mainarray[$i][6] = 0
                $mainarray[$i][4] = $forward
                If $forward = "0" Then
                    _Send_Response($mainarray[$i][1],400)
                    _save("]" & $i &" Host is 0 , Error 400" & @CRLF)
                Else
                        $serverip   = TCPNameToIP($forward)
                        $serversock = TCPConnect($serverip,$mainarray[$i][0])
                        If $serversock <> -1 Then
                            _save("]" & $i &" Connected to Server: " & $forward & @CRLF)
                            $mainarray[$i][2] = $serversock
                            $mainarray[$i][5] = TimerInit()
                        Else
                            _save("]" & $i &" Not Connected to Server: " & $forward & @CRLF)
                            _Send_Response($mainarray[$i][1],400)
                            _mainarray_deleteclient($i)
                        EndIf
                EndIf   
            Else
                $forward = _Get_Address($mainarray[$i][3])
                If $forward <> $mainarray[$i][4] Then
                    _save("]" & $i &" Host Address changed from: " & $mainarray[$i][4] & " to: " & $forward & @CRLF)
                    $mainarray[$i][4] = $forward
                    TCPCloseSocket($mainarray[$i][2])
                    $mainarray[$i][2] = ""
                EndIf
            EndIf
            If $mainarray[$i][2] <> "" Then
                $mainarray[$i][3] = _request_modify($mainarray[$i][3],$mainarray[$i][4])
                TCPSend($mainarray[$i][2] , $mainarray[$i][3])
                If Not @error Then
                    $mainarray[$i][3] = ""
                    _save("]" & $i &" Sending to Host " & $mainarray[$i][4] & " successfull " & @CRLF)
                Else
                    _save("]" & $i &" Error Sending to Host " & @CRLF)
                EndIf
            EndIf
        EndIf
    Next
    ;--Waiting for Response from Host and Sending to client
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][2] <> "" Then
            $serverresponse     = TCPRecv($mainarray[$i][2],400000,1)   
            If @error Then 
                _mainarray_hostkillclient($i)
            EndIf
            If $serverresponse <> Binary("") Then
                If $mainarray[$i][6] = 0 Then 
                    _save("]" & $i &" Got Host response" & @CRLF)
                    If  $mainarray[$i][1] <> "" And $mainarray[$i][7] = "" Then
                        TCPSend($mainarray[$i][1],$serverresponse)
                        If Not @error Then
                            _save("]" & $i &" Send data to Browser last 4 :"  & StringRight($serverresponse,4) & @CRLF)
                            If GUICtrlRead($checkbox_debug_content) = 1 Then _save(BinaryToString($serverresponse) & @CRLF)
                        EndIf       
                    EndIf   
                ElseIf $mainarray[$i][6] = 1 Then 
                    TCPSend($mainarray[$i][1],"HTTP/1.1 " & "403")
                    _mainarray_hostkillclient($i)
                EndIf
            EndIf
        EndIf
    Next    

WEnd    


Func _show_array()
    _ArrayDisplay($mainarray)
EndFunc

Func _mainsocket_save()
    IniWrite($ini,"SYSTEM","PROXYPORT",GUICtrlRead($input_proxyport))
    IniWrite($ini,"SYSTEM","PROXYIP",GUICtrlRead($input_proxyip))
    IniWrite($ini,"SYSTEM","PROXYPORTSSL",GUICtrlRead($input_proxyportssl))
    _mainsocket_create()
EndFunc

Func _mainsocket_create()
    TCPShutdown()
    TCPStartup()
    $IP = IniRead($ini,"SYSTEM","PROXYIP","127.0.0.1")
    $PORT = IniRead($ini,"SYSTEM","PROXYPORT","8080")
    $PORTSSL = IniRead($ini,"SYSTEM","PROXYPORTSSL","8043")
    GUICtrlSetData($input_proxyip, $IP)
    GUICtrlSetData($input_proxyport,$PORT)
    GUICtrlSetData($input_proxyportssl,$PORTSSL)
    $proxysocket        = TCPListen($IP,$PORT)
    If @error Then 
        _GUICtrlEdit_AppendText($DEBUG , "] Error HTTP Proxy couldn't bind socket on IP :" & $IP & " Port :" & $PORT & @CRLF)
    Else
        _GUICtrlEdit_AppendText($DEBUG , "] HTTP Proxy listening on IP :" & $IP & " Port :" & $PORT & @CRLF)
    EndIf   
    $proxysocketssl     = TCPListen($IP,$PORTSSL)
    If @error Then 
        _GUICtrlEdit_AppendText($DEBUG , "] Error HTTPS Proxy couldn't bind socket on IP :" & $IP & " Port :" & $PORTSSL & @CRLF)
    Else
        _GUICtrlEdit_AppendText($DEBUG , "] HTTPS Proxy listening on IP :" & $IP & " Port :" & $PORTSSL & @CRLF)
    EndIf       
EndFunc

Func _Get_Address($text)
    $serversock=StringSplit($text , @CRLF,1)
    For $i=1 To $serversock[0]
        If StringLeft($serversock[$i],6)="Host: " Then
            Return StringTrimLeft($serversock[$i],6)
        EndIf
    Next
    Return 0        
EndFunc

Func _clientconnection_to_mainarray($sock,$port = 80,$type = "HTTP")
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] = "" And $mainarray[$i][2] = "" Then
            $mainarray[$i][1] = $sock
            $mainarray[$i][0] = $port
            $mainarray[$i][8] = $type
            _save("] Added new client to mainarray , pos: " & $i & @CRLF)
            Return
        EndIf   
    Next
EndFunc

Func _mainarray_deleteclient($line)
    TCPCloseSocket($mainarray[$line][1])
    $mainarray[$line][0] = ""
    $mainarray[$line][1] = ""
    $mainarray[$line][3] = ""
    $mainarray[$line][4] = ""
    $mainarray[$line][5] = ""
    $mainarray[$line][6] = ""
    $mainarray[$line][7] = ""
    $mainarray[$line][8] = ""
    If $mainarray[$line][2]<> "" Then
        TCPCloseSocket($mainarray[$line][2])
        $mainarray[$line][2] = ""
    EndIf
EndFunc

Func _mainarray_hostkillclient($line)
    _save("]" & $line &" Connection Closed by Host" & @CRLF)
    $mainarray[$line][2] = ""
    $mainarray[$line][4] = ""
    $mainarray[$line][5] = ""
    If $mainarray[$line][1]<> "" Then
        TCPCloseSocket($mainarray[$line][1])
        _mainarray_deleteclient($line)
    EndIf   
EndFunc

Func _Send_Response($browsersock,$code,$data="")
    If $data="" Then
        $data=@CRLF & @CRLF 
    Else
        $data=@CRLF & $data & @CRLF & @CRLF 
    EndIf
    TCPSend($browsersock , "HTTP/1.0 " & $code & " Message" & $data)
EndFunc

Func _quit()
    TCPShutdown()
    Exit
EndFunc

Func _gui_show()
    If $GUISHOW = 0 Then
        Local $pw = InputBox("Enter Password","Enter Password","","*",150,130)
        If Not @error Then
            If $pw = "1234" Then 
                GUISetState(@SW_SHOW)
                $GUISHOW = 1
                Return
            EndIf   
        EndIf
    ElseIf $GUISHOW = 1 Then
        GUISetState(@SW_HIDE)
        $GUISHOW = 0
        Return      
    EndIf
EndFunc 

Func _save($text)
    If GUICtrlRead($checkbox_debug_save) = 1 Then
        $file = FileOpen(@ScriptDir & "\log\" & @Year & @MON & @MDAY & "-log.txt",9)
        FileWrite ($file,$text)
        FileClose($file)
    Endif
    If GUICtrlRead($checkbox_debug) = 1 Then _GUICtrlEdit_AppendText($DEBUG , $text)
Endfunc

Func _SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")
    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0
    Return $aRet
EndFunc   ;==>SocketToIP

Func _debug_binary()
    Local $aSel = _GUICtrlEdit_GetSel($DEBUG)
    Local $text = StringMid(GUICtrlRead($DEBUG),$aSel[0]+1,$aSel[1]-$aSel[0])
    If $text <> "" Then 

    Else    
        $text = InputBox("Binary to String","Enter Binary Data") 
        EndIf
    If StringLower(StringLeft($text,2)) <> "0x" Then $text = "0x" & $text
    $tempfile = FileOpen(@ScriptDir & "\temp.txt",2)
    FileWrite($tempfile,BinaryToString($text))
    FileClose($tempfile)
    ShellExecute(@ScriptDir & "\temp.txt")
EndFunc 

Func _debug_clear()
    GUICtrlSetData($DEBUG,"")
EndFunc 

Func _request_modify($req,$host)
        Local $encoding = "Accept-Encoding: identity" ;deflate, gzip, compress, 
        Local $reqsplit
        Local $encoding_done = 0
        If $req <> "" Then
        ;$req = StringReplace($req,@CRLF & @CRLF , @CRLF)
        $reqsplit = StringSplit($req,@CRLF,1)       
        If IsArray($reqsplit) Then
            For $i = 1 to $reqsplit[0]
                If StringLeft($reqsplit[$i],3) = "GET" Then
                    $wwwcount = StringInStr($reqsplit[$i],"www.",0,2)
                    If $wwwcount = 0 Then 
                        $reqsplit[$i] = StringReplace($reqsplit[$i],$host,"")
                        $reqsplit[$i] = StringReplace($reqsplit[$i],"http://","")
                    EndIf
                EndIf 
                If StringInStr(Stringlower($reqsplit[$i]),"proxy-connection: keep-alive") Then $reqsplit[$i] = "Connection: keep-alive"
                If StringInStr(Stringlower($reqsplit[$i]),"accept-encoding") Then
                    $reqsplit[$i] = $encoding
                    $encoding_done = 1
                EndIf
            $reqsplit[$i] = StringReplace($reqsplit[$i],@CRLF,"")
            Next    
            ;If $encoding_done = 0 Then _ArrayInsert($reqsplit,$reqsplit[0], $encoding)
            $req = _ArrayToString($reqsplit, @CRLF , 1 , Ubound($reqsplit)-1)
        EndIf
    EndIf
    $req = StringReplace($req,":443","")
    If GUICtrlRead($checkbox_debug_content) = 1 Then
        _save("] Request modified to:" & @CRLF)
        _save($req &@CRLF)
    EndIf
    Return $req
EndFunc

Enrico

Share this post


Link to post
Share on other sites
lionel

Hello,

I know this topic is old but I have another working version of a Proxyserver in AutoIT.

It's not perfect written but it works perfect and fast.

I started implementing HTTPS but isn't finished yet.

TCPStartup()
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GUIEdit.au3>
#Include <Array.au3>
#Include <File.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode" , 1)
Opt("TrayAutoPause",0)
Opt("TrayMenuMode",3)
Opt("TrayOnEventMode",1)

Global $ini = @ScriptDir & "\config.ini" 
Global $mainarray[51][10]
Global $proxysocket , $proxysocketssl
Global $GUISHOW = 1

$mainarray[0][0] = "Hostport"
$mainarray[0][1] = "Clientsocket"
$mainarray[0][2] = "Hostsocket"
$mainarray[0][3] = "Request"
$mainarray[0][4] = "Hostname"
$mainarray[0][5] = "Timerhandle Hostconnection"
$mainarray[0][6] = "Blocked"
$mainarray[0][7] = "State"
$mainarray[0][8] = "connection type"


Global $gui = GUICreate("ProxyServer v0.2",700,700)
$DEBUG=GUICtrlCreateEdit("" , 5 , 30 , 500 ,670,BitOr($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUICtrlSetLimit(-1 , 2000000000000000)
Global $button_debug_clear = GUICtrlCreateButton("Clear",5,5,90,20)
GUICtrlSetOnEvent($button_debug_clear,"_debug_clear")
GUICtrlCreateLabel("Listening IP:",515,40,70,20)
GUICtrlCreateLabel("Port HTTP:",515,60,70,20)
GUICtrlCreateLabel("Port HTTPS:",515,80,70,20)
Global $input_proxyip =  GUICtrlCreateInput("",590, 40,100,20)
Global $input_proxyport = GUICtrlCreateInput("",590,60,60,20)
Global $input_proxyportssl = GUICtrlCreateInput("",590,80,60,20)
Global $button_proxy_save = GUICtrlCreateButton("Save and Restart",515,140,180,20)
GUICtrlSetOnEvent($button_proxy_save,"_mainsocket_save")
Global $checkbox_debug = GUICtrlCreateCheckbox("Debugmode", 515 , 240, 120, 20)
Global $checkbox_debug_save = GUICtrlCreateCheckbox("Save Debug to file", 515 , 260, 120, 20)
Global $checkbox_debug_content = GUICtrlCreateCheckbox("Show traffic content", 515 , 280, 120, 20)
Global $button_debug_content = GUICtrlCreateButton("Binary to String",515,320,120,19)
GUICtrlSetOnEvent($button_debug_content,"_debug_binary")
Global $button_debug_array = GUICtrlCreateButton("show mainarray",515,340,120,19)
GUICtrlSetOnEvent(-1,"_show_array")


Global $tray_showgui = TrayCreateItem("Show gui")
TrayItemSetOnEvent($tray_showgui,"_gui_show")

GUISetOnEvent($GUI_EVENT_CLOSE,"_quit")
GUISetState(@SW_SHOW,$gui)

_mainsocket_create()

While 1

    $newclientsock  = TCPAccept($proxysocket)
    If $newclientsock <> -1 Then
        _save("] new HTTP clientconnection :" &_SocketToIP($newclientsock) &@CRLF) 
        _clientconnection_to_mainarray($newclientsock,80,"HTTP")
    EndIf
    $newclientsockssl   = TCPAccept($proxysocketssl)
    If $newclientsockssl <> -1 Then
        _save("] new HTTPS clientconnection :" &_SocketToIP($newclientsockssl) &@CRLF) 
        _clientconnection_to_mainarray($newclientsockssl,443,"HTTPS")
    EndIf

    ;--Recieving Req from Client
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] <> "" Then
            $request = TCPRecv($mainarray[$i][1],4096)
            If @error Then 
                _mainarray_deleteclient($i)
                _save("] Client " & $i & " closed connection" & @CRLF)
            EndIf
            If $request <> "" Then
                _save("] Client " & $i & " requested" & @CRLF & $request)
                $mainarray[$i][3] = $request
                If GUICtrlRead($checkbox_debug_content) = 1 Then _save($request & @CRLF)
            EndIf   
        EndIf
    Next
    ;--connecting and sending Req to Host
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][3] <> "" Then
            If $mainarray[$i][2] = "" Then
                $forward = _Get_Address($mainarray[$i][3])
                _save("]" & $i &" Got Host Address : " & $forward & @CRLF)          
                $mainarray[$i][6] = 0
                $mainarray[$i][4] = $forward
                If $forward = "0" Then
                    _Send_Response($mainarray[$i][1],400)
                    _save("]" & $i &" Host is 0 , Error 400" & @CRLF)
                Else
                        $serverip   = TCPNameToIP($forward)
                        $serversock = TCPConnect($serverip,$mainarray[$i][0])
                        If $serversock <> -1 Then
                            _save("]" & $i &" Connected to Server: " & $forward & @CRLF)
                            $mainarray[$i][2] = $serversock
                            $mainarray[$i][5] = TimerInit()
                        Else
                            _save("]" & $i &" Not Connected to Server: " & $forward & @CRLF)
                            _Send_Response($mainarray[$i][1],400)
                            _mainarray_deleteclient($i)
                        EndIf
                EndIf   
            Else
                $forward = _Get_Address($mainarray[$i][3])
                If $forward <> $mainarray[$i][4] Then
                    _save("]" & $i &" Host Address changed from: " & $mainarray[$i][4] & " to: " & $forward & @CRLF)
                    $mainarray[$i][4] = $forward
                    TCPCloseSocket($mainarray[$i][2])
                    $mainarray[$i][2] = ""
                EndIf
            EndIf
            If $mainarray[$i][2] <> "" Then
                $mainarray[$i][3] = _request_modify($mainarray[$i][3],$mainarray[$i][4])
                TCPSend($mainarray[$i][2] , $mainarray[$i][3])
                If Not @error Then
                    $mainarray[$i][3] = ""
                    _save("]" & $i &" Sending to Host " & $mainarray[$i][4] & " successfull " & @CRLF)
                Else
                    _save("]" & $i &" Error Sending to Host " & @CRLF)
                EndIf
            EndIf
        EndIf
    Next
    ;--Waiting for Response from Host and Sending to client
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][2] <> "" Then
            $serverresponse     = TCPRecv($mainarray[$i][2],400000,1)   
            If @error Then 
                _mainarray_hostkillclient($i)
            EndIf
            If $serverresponse <> Binary("") Then
                If $mainarray[$i][6] = 0 Then 
                    _save("]" & $i &" Got Host response" & @CRLF)
                    If  $mainarray[$i][1] <> "" And $mainarray[$i][7] = "" Then
                        TCPSend($mainarray[$i][1],$serverresponse)
                        If Not @error Then
                            _save("]" & $i &" Send data to Browser last 4 :"  & StringRight($serverresponse,4) & @CRLF)
                            If GUICtrlRead($checkbox_debug_content) = 1 Then _save(BinaryToString($serverresponse) & @CRLF)
                        EndIf       
                    EndIf   
                ElseIf $mainarray[$i][6] = 1 Then 
                    TCPSend($mainarray[$i][1],"HTTP/1.1 " & "403")
                    _mainarray_hostkillclient($i)
                EndIf
            EndIf
        EndIf
    Next    

WEnd    


Func _show_array()
    _ArrayDisplay($mainarray)
EndFunc

Func _mainsocket_save()
    IniWrite($ini,"SYSTEM","PROXYPORT",GUICtrlRead($input_proxyport))
    IniWrite($ini,"SYSTEM","PROXYIP",GUICtrlRead($input_proxyip))
    IniWrite($ini,"SYSTEM","PROXYPORTSSL",GUICtrlRead($input_proxyportssl))
    _mainsocket_create()
EndFunc

Func _mainsocket_create()
    TCPShutdown()
    TCPStartup()
    $IP = IniRead($ini,"SYSTEM","PROXYIP","127.0.0.1")
    $PORT = IniRead($ini,"SYSTEM","PROXYPORT","8080")
    $PORTSSL = IniRead($ini,"SYSTEM","PROXYPORTSSL","8043")
    GUICtrlSetData($input_proxyip, $IP)
    GUICtrlSetData($input_proxyport,$PORT)
    GUICtrlSetData($input_proxyportssl,$PORTSSL)
    $proxysocket        = TCPListen($IP,$PORT)
    If @error Then 
        _GUICtrlEdit_AppendText($DEBUG , "] Error HTTP Proxy couldn't bind socket on IP :" & $IP & " Port :" & $PORT & @CRLF)
    Else
        _GUICtrlEdit_AppendText($DEBUG , "] HTTP Proxy listening on IP :" & $IP & " Port :" & $PORT & @CRLF)
    EndIf   
    $proxysocketssl     = TCPListen($IP,$PORTSSL)
    If @error Then 
        _GUICtrlEdit_AppendText($DEBUG , "] Error HTTPS Proxy couldn't bind socket on IP :" & $IP & " Port :" & $PORTSSL & @CRLF)
    Else
        _GUICtrlEdit_AppendText($DEBUG , "] HTTPS Proxy listening on IP :" & $IP & " Port :" & $PORTSSL & @CRLF)
    EndIf       
EndFunc

Func _Get_Address($text)
    $serversock=StringSplit($text , @CRLF,1)
    For $i=1 To $serversock[0]
        If StringLeft($serversock[$i],6)="Host: " Then
            Return StringTrimLeft($serversock[$i],6)
        EndIf
    Next
    Return 0        
EndFunc

Func _clientconnection_to_mainarray($sock,$port = 80,$type = "HTTP")
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] = "" And $mainarray[$i][2] = "" Then
            $mainarray[$i][1] = $sock
            $mainarray[$i][0] = $port
            $mainarray[$i][8] = $type
            _save("] Added new client to mainarray , pos: " & $i & @CRLF)
            Return
        EndIf   
    Next
EndFunc

Func _mainarray_deleteclient($line)
    TCPCloseSocket($mainarray[$line][1])
    $mainarray[$line][0] = ""
    $mainarray[$line][1] = ""
    $mainarray[$line][3] = ""
    $mainarray[$line][4] = ""
    $mainarray[$line][5] = ""
    $mainarray[$line][6] = ""
    $mainarray[$line][7] = ""
    $mainarray[$line][8] = ""
    If $mainarray[$line][2]<> "" Then
        TCPCloseSocket($mainarray[$line][2])
        $mainarray[$line][2] = ""
    EndIf
EndFunc

Func _mainarray_hostkillclient($line)
    _save("]" & $line &" Connection Closed by Host" & @CRLF)
    $mainarray[$line][2] = ""
    $mainarray[$line][4] = ""
    $mainarray[$line][5] = ""
    If $mainarray[$line][1]<> "" Then
        TCPCloseSocket($mainarray[$line][1])
        _mainarray_deleteclient($line)
    EndIf   
EndFunc

Func _Send_Response($browsersock,$code,$data="")
    If $data="" Then
        $data=@CRLF & @CRLF 
    Else
        $data=@CRLF & $data & @CRLF & @CRLF 
    EndIf
    TCPSend($browsersock , "HTTP/1.0 " & $code & " Message" & $data)
EndFunc

Func _quit()
    TCPShutdown()
    Exit
EndFunc

Func _gui_show()
    If $GUISHOW = 0 Then
        Local $pw = InputBox("Enter Password","Enter Password","","*",150,130)
        If Not @error Then
            If $pw = "1234" Then 
                GUISetState(@SW_SHOW)
                $GUISHOW = 1
                Return
            EndIf   
        EndIf
    ElseIf $GUISHOW = 1 Then
        GUISetState(@SW_HIDE)
        $GUISHOW = 0
        Return      
    EndIf
EndFunc 

Func _save($text)
    If GUICtrlRead($checkbox_debug_save) = 1 Then
        $file = FileOpen(@ScriptDir & "\log\" & @Year & @MON & @MDAY & "-log.txt",9)
        FileWrite ($file,$text)
        FileClose($file)
    Endif
    If GUICtrlRead($checkbox_debug) = 1 Then _GUICtrlEdit_AppendText($DEBUG , $text)
Endfunc

Func _SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")
    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0
    Return $aRet
EndFunc   ;==>SocketToIP

Func _debug_binary()
    Local $aSel = _GUICtrlEdit_GetSel($DEBUG)
    Local $text = StringMid(GUICtrlRead($DEBUG),$aSel[0]+1,$aSel[1]-$aSel[0])
    If $text <> "" Then 

    Else    
        $text = InputBox("Binary to String","Enter Binary Data") 
        EndIf
    If StringLower(StringLeft($text,2)) <> "0x" Then $text = "0x" & $text
    $tempfile = FileOpen(@ScriptDir & "\temp.txt",2)
    FileWrite($tempfile,BinaryToString($text))
    FileClose($tempfile)
    ShellExecute(@ScriptDir & "\temp.txt")
EndFunc 

Func _debug_clear()
    GUICtrlSetData($DEBUG,"")
EndFunc 

Func _request_modify($req,$host)
        Local $encoding = "Accept-Encoding: identity" ;deflate, gzip, compress, 
        Local $reqsplit
        Local $encoding_done = 0
        If $req <> "" Then
        ;$req = StringReplace($req,@CRLF & @CRLF , @CRLF)
        $reqsplit = StringSplit($req,@CRLF,1)       
        If IsArray($reqsplit) Then
            For $i = 1 to $reqsplit[0]
                If StringLeft($reqsplit[$i],3) = "GET" Then
                    $wwwcount = StringInStr($reqsplit[$i],"www.",0,2)
                    If $wwwcount = 0 Then 
                        $reqsplit[$i] = StringReplace($reqsplit[$i],$host,"")
                        $reqsplit[$i] = StringReplace($reqsplit[$i],"http://","")
                    EndIf
                EndIf 
                If StringInStr(Stringlower($reqsplit[$i]),"proxy-connection: keep-alive") Then $reqsplit[$i] = "Connection: keep-alive"
                If StringInStr(Stringlower($reqsplit[$i]),"accept-encoding") Then
                    $reqsplit[$i] = $encoding
                    $encoding_done = 1
                EndIf
            $reqsplit[$i] = StringReplace($reqsplit[$i],@CRLF,"")
            Next    
            ;If $encoding_done = 0 Then _ArrayInsert($reqsplit,$reqsplit[0], $encoding)
            $req = _ArrayToString($reqsplit, @CRLF , 1 , Ubound($reqsplit)-1)
        EndIf
    EndIf
    $req = StringReplace($req,":443","")
    If GUICtrlRead($checkbox_debug_content) = 1 Then
        _save("] Request modified to:" & @CRLF)
        _save($req &@CRLF)
    EndIf
    Return $req
EndFunc

Enrico

(I'm sorry for my english, I'm french)

It's very good work!

It's finish for HTTPS?

Thx

Share this post


Link to post
Share on other sites
EnrMa

For HTTPS you don't have to decrypt the datastream.

You only have to forward the data ( I think it is so ). If the proxy gets the request , the proxy has to send data back to the browser and the browser must acceppt this.

I try to implement it in the next days.

Enrico

Share this post


Link to post
Share on other sites
EnrMa

So, HTTPS is working for me , you can try it.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_outfile=proxy.exe
#AutoIt3Wrapper_Compression=4
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
TCPStartup()
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GUIEdit.au3>
#Include <Array.au3>
#Include <File.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode" , 1)
Opt("TrayAutoPause",0)
Opt("TrayMenuMode",3)
Opt("TrayOnEventMode",1)

Global $ini = @ScriptDir & "\config.ini" 
Global $mainarray[30][10]
Global $proxysocket , $proxysocketssl
Global $GUISHOW = 1

$mainarray[0][0] = "Hostport"
$mainarray[0][1] = "Clientsocket"
$mainarray[0][2] = "Hostsocket"
$mainarray[0][3] = "Request"
$mainarray[0][4] = "Hostname"
$mainarray[0][5] = "Timerhandle connection"
$mainarray[0][6] = "Blocked"
$mainarray[0][7] = "State"
$mainarray[0][8] = "connection type"
$mainarray[0][9] = "req count"



Global $gui = GUICreate("ProxyServer v0.2",700,700)
$DEBUG=GUICtrlCreateEdit("" , 5 , 30 , 500 ,670,BitOr($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUICtrlSetLimit(-1 , 2000000000000000)
Global $button_debug_clear = GUICtrlCreateButton("Clear",5,5,90,20)
GUICtrlSetOnEvent($button_debug_clear,"_debug_clear")
GUICtrlCreateLabel("Listening IP:",515,40,70,20)
GUICtrlCreateLabel("Port HTTP:",515,60,70,20)
GUICtrlCreateLabel("Port HTTPS:",515,80,70,20)
Global $input_proxyip =  GUICtrlCreateInput("",590, 40,100,20)
Global $input_proxyport = GUICtrlCreateInput("",590,60,60,20)
Global $input_proxyportssl = GUICtrlCreateInput("",590,80,60,20)
Global $button_proxy_save = GUICtrlCreateButton("Save and Restart",515,140,180,20)
GUICtrlSetOnEvent($button_proxy_save,"_mainsocket_save")

Global $checkbox_debug = GUICtrlCreateCheckbox("Debugmode", 515 , 240, 120, 20)
Global $checkbox_debug_save = GUICtrlCreateCheckbox("Save Debug to file", 515 , 260, 120, 20)
Global $checkbox_debug_content = GUICtrlCreateCheckbox("Show traffic content", 515 , 280, 120, 20)
Global $button_debug_content = GUICtrlCreateButton("Binary to String",515,320,120,19)
GUICtrlSetOnEvent($button_debug_content,"_debug_binary")
Global $button_debug_array = GUICtrlCreateButton("show mainarray",515,340,120,19)
GUICtrlSetOnEvent(-1,"_show_array")


Global $tray_showgui = TrayCreateItem("Show gui")
TrayItemSetOnEvent($tray_showgui,"_gui_show")

GUISetOnEvent($GUI_EVENT_CLOSE,"_quit")
GUISetState(@SW_SHOW,$gui)

_mainsocket_create()

While 1
    $newclientsock  = TCPAccept($proxysocket)
    If $newclientsock <> -1 Then
        _save("] new HTTP clientconnection :" &_SocketToIP($newclientsock) &@CRLF) 
        _clientconnection_to_mainarray($newclientsock,80,"HTTP")
    EndIf
    $newclientsockssl   = TCPAccept($proxysocketssl)
    If $newclientsockssl <> -1 Then
        _save("] new HTTPS clientconnection :" &_SocketToIP($newclientsockssl) &@CRLF) 
        _clientconnection_to_mainarray($newclientsockssl,443,"HTTPS","start")
    EndIf
    ;--Recieving Req from Client
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] <> "" Then
            $request = TCPRecv($mainarray[$i][1],100000)
            If @error Then 
                
                _save("] Client " & $i & " closed connection after " & Floor(TimerDiff($mainarray[$i][5])) & " ms" & @CRLF)
                _mainarray_deleteclient($i)
            EndIf
            
            If $request <> "" Then
                _save("] Client " & $i & " requested" & @CRLF  & @CRLF & $request & @CRLF)
                $mainarray[$i][9] += 1 
                $mainarray[$i][3] = $request
                If GUICtrlRead($checkbox_debug_content) = 1 Then _save($request & @CRLF)
            EndIf   
        EndIf
    Next

    ;--connecting and sending Req to Host
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][3] <> "" Then
            If $mainarray[$i][2] = "" Then
                $forward = _Get_Address($mainarray[$i][3])
                _save("]" & $i &" Got Host Address : " & $forward  & @CRLF)         
                $mainarray[$i][6] = 0
                $mainarray[$i][4] = $forward
                If $forward = "0" Then
                    _Send_Response($mainarray[$i][1],400)
                    _save("]" & $i &" Host is 0 , Error 400" & @CRLF)
                Else
                        $serverip   = TCPNameToIP($forward)
                        $serversock = TCPConnect($serverip,$mainarray[$i][0])
                        If $serversock <> -1 Then
                            _save("]" & $i &" Connected to Host: " & $forward & @CRLF)
                            $mainarray[$i][2] = $serversock
                            
                        Else
                            _save("]" & $i &" Not Connected to Host: " & $forward & @CRLF)
                            _Send_Response($mainarray[$i][1],400)
                            _mainarray_deleteclient($i)
                        EndIf
                EndIf   
            Else
                $forward = _Get_Address($mainarray[$i][3])
                If $forward <> $mainarray[$i][4] Then
                    _save("]" & $i &" Host Address changed from: " & $mainarray[$i][4] & " to: " & $forward & @CRLF)
                    $mainarray[$i][4] = $forward
                    TCPCloseSocket($mainarray[$i][2])
                    $mainarray[$i][2] = ""
                EndIf
            EndIf
            If $mainarray[$i][2] <> "" Then
                $prevlen = StringLen($mainarray[$i][3])
                $mainarray[$i][3] = _request_modify($mainarray[$i][3],$mainarray[$i][4])
                If $mainarray[$i][7] = "" Then 
                    ;$mainarray[$i][3] = _request_modify($mainarray[$i][3],$mainarray[$i][4])
                    TCPSend($mainarray[$i][2] , $mainarray[$i][3])
                        If Not @error Then
                            _save("]" & $i &" Sending HTTP to Host " & $mainarray[$i][4] & " successfull prevlen:" & $prevlen & " now:" & StringLen($mainarray[$i][3]) & @CRLF)
                            $mainarray[$i][3] = ""
                        Else
                            _save("]" & $i &" Error Sending HTTP to Host " & @CRLF)
                        EndIf
                EndIf
            EndIf
        EndIf
    Next
    ;--Waiting for Response from Host and Sending to client
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][2] <> "" Then
            $serverresponse     = TCPRecv($mainarray[$i][2],400000,1)   
            If @error Then 
                _mainarray_hostkillclient($i)
            EndIf
            If $serverresponse <> Binary("") Then
                If $mainarray[$i][6] = 0 Then 
                    _save("]" & $i &" Got Host response" & @CRLF)
                    If  $mainarray[$i][1] <> "" And $mainarray[$i][7] = "" Then
                        TCPSend($mainarray[$i][1],$serverresponse)
                        If Not @error Then
                            _save("]" & $i &" Sent data to Client " & @CRLF)

                            If GUICtrlRead($checkbox_debug_content) = 1 Then _save(BinaryToString($serverresponse) & @CRLF)
                        EndIf       
                    EndIf   
                ElseIf $mainarray[$i][6] = 1 Then 
                    TCPSend($mainarray[$i][1],"HTTP/1.1 " & "403")
                    _mainarray_hostkillclient($i)
                EndIf
            EndIf
        EndIf
    Next    
    ;---only for HTTPS
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] <> "" And $mainarray[$i][3] <> "" And $mainarray[$i][8] = "HTTPS" And $mainarray[$i][7] = "start" Then
            _Send_Response($mainarray[$i][1],200) ;,$data="")
            $mainarray[$i][3] = ""
            $mainarray[$i][7] = ""
        EndIf
    Next
    
WEnd    

Func _show_array()
    _ArrayDisplay($mainarray)
EndFunc

Func _mainsocket_save()
    IniWrite($ini,"SYSTEM","PROXYPORT",GUICtrlRead($input_proxyport))
    IniWrite($ini,"SYSTEM","PROXYIP",GUICtrlRead($input_proxyip))
    IniWrite($ini,"SYSTEM","PROXYPORTSSL",GUICtrlRead($input_proxyportssl))
    _mainsocket_create()
EndFunc

Func _mainsocket_create()
    TCPShutdown()
    TCPStartup()
    $IP = IniRead($ini,"SYSTEM","PROXYIP","127.0.0.1")
    $PORT = IniRead($ini,"SYSTEM","PROXYPORT","8080")
    $PORTSSL = IniRead($ini,"SYSTEM","PROXYPORTSSL","8043")
    GUICtrlSetData($input_proxyip, $IP)
    GUICtrlSetData($input_proxyport,$PORT)
    GUICtrlSetData($input_proxyportssl,$PORTSSL)
    $proxysocket        = TCPListen($IP,$PORT)
    If @error Then 
        _GUICtrlEdit_AppendText($DEBUG , "] Error HTTP Proxy couldn't bind socket on IP :" & $IP & " Port :" & $PORT & @CRLF)
    Else
        _GUICtrlEdit_AppendText($DEBUG , "] HTTP Proxy listening on IP :" & $IP & " Port :" & $PORT & @CRLF)
    EndIf   
    $proxysocketssl     = TCPListen($IP,$PORTSSL)
    If @error Then 
        _GUICtrlEdit_AppendText($DEBUG , "] Error HTTPS Proxy couldn't bind socket on IP :" & $IP & " Port :" & $PORTSSL & @CRLF)
    Else
        _GUICtrlEdit_AppendText($DEBUG , "] HTTPS Proxy listening on IP :" & $IP & " Port :" & $PORTSSL & @CRLF)
    EndIf       
EndFunc


Func _Get_Address($text)
    If IsBinary($text) Then 
        $text = BinaryToString($text)
    EndIf
        $serversock=StringSplit($text , @CRLF,1)
        For $i=1 To $serversock[0]
            If StringLeft($serversock[$i],6)="Host: " Then
                Return StringTrimLeft($serversock[$i],6)
            EndIf
        Next
    Return 0        
EndFunc

Func _clientconnection_to_mainarray($sock,$port = 80,$type = "HTTP",$state = "")
    For $i = 1 To UBound($mainarray) -1
        If $mainarray[$i][1] = "" And $mainarray[$i][2] = "" Then
            $mainarray[$i][1] = $sock
            $mainarray[$i][0] = $port
            $mainarray[$i][5] = TimerInit()
            $mainarray[$i][7] = $state
            $mainarray[$i][8] = $type
            _save("] Added new client to mainarray , pos: " & $i & @CRLF)
            If $i + 5 > UBound($mainarray) Then ReDim $mainarray[UBound($mainarray)+5][10]
            Return
        EndIf   
    Next
EndFunc

Func _mainarray_deleteclient($line)
    TCPCloseSocket($mainarray[$line][1])
    $mainarray[$line][0] = ""
    $mainarray[$line][1] = ""
    $mainarray[$line][3] = ""
    $mainarray[$line][4] = ""
    $mainarray[$line][5] = ""
    $mainarray[$line][6] = ""
    $mainarray[$line][7] = ""
    $mainarray[$line][8] = ""
    $mainarray[$line][9] = ""
    If $mainarray[$line][2]<> "" Then
        TCPCloseSocket($mainarray[$line][2])
        $mainarray[$line][2] = ""
    EndIf
EndFunc

Func _mainarray_hostkillclient($line)
    _save("]" & $line &" Connection Closed by Host after " & Floor(TimerDiff($mainarray[$line][5])) & " ms" & @CRLF)
    $mainarray[$line][2] = ""
    $mainarray[$line][4] = ""
    $mainarray[$line][5] = ""
    If $mainarray[$line][1]<> "" Then
        TCPCloseSocket($mainarray[$line][1])
        _mainarray_deleteclient($line)
    EndIf   
EndFunc

Func _Send_Response($browsersock,$code,$data="")
    If $data="" Then
        $data=@CRLF & @CRLF 
    Else
        $data=@CRLF & $data & @CRLF & @CRLF 
    EndIf
    TCPSend($browsersock , "HTTP/1.0 " & $code & " Message" & $data)
EndFunc


Func _quit()
    TCPShutdown()
    Exit
EndFunc

Func _gui_show()
    If $GUISHOW = 0 Then
        Local $pw = InputBox("Enter Password","Enter Password","","*",150,130)
        If Not @error Then
            If $pw = "1234" Then 
                GUISetState(@SW_SHOW)
                $GUISHOW = 1
                Return
            EndIf   
        EndIf
    ElseIf $GUISHOW = 1 Then
        GUISetState(@SW_HIDE)
        $GUISHOW = 0
        Return      
    EndIf
EndFunc 

Func _save($text)
    If GUICtrlRead($checkbox_debug_save) = 1 Then
        $file = FileOpen(@ScriptDir & "\log\" & @Year & @MON & @MDAY & "-log.txt",9)
        FileWrite ($file,$text)
        FileClose($file)
    Endif
    If GUICtrlRead($checkbox_debug) = 1 Then _GUICtrlEdit_AppendText($DEBUG , $text)
Endfunc

Func _SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")
    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf
    $sockaddr = 0
    Return $aRet
EndFunc   ;==>SocketToIP

Func _debug_binary()
    Local $aSel = _GUICtrlEdit_GetSel($DEBUG)
    Local $text = StringMid(GUICtrlRead($DEBUG),$aSel[0]+1,$aSel[1]-$aSel[0])
    If $text <> "" Then 
        
    Else    
        $text = InputBox("Binary to String","Enter Binary Data") 
        
    EndIf
    If StringLower(StringLeft($text,2)) <> "0x" Then $text = "0x" & $text
    $tempfile = FileOpen(@ScriptDir & "\temp.txt",2)
    FileWrite($tempfile,BinaryToString($text))
    FileClose($tempfile)
    ShellExecute(@ScriptDir & "\temp.txt")
EndFunc 

Func _debug_clear()
    GUICtrlSetData($DEBUG,"")
EndFunc 

Func _request_modify($req,$host)
Local $encoding = "Accept-Encoding: identity" ;deflate, gzip, compress, 
Local $reqsplit
Local $modified_method = 0 , $modified_connection = 0 , $modified_encoding = 0
    If $req <> "" And Not IsBinary($req) Then
        $reqsplit = StringSplit($req,@CRLF,1)       
        If IsArray($reqsplit) Then
            For $i = 1 to $reqsplit[0] - 1
                _save("] modifying :" & $i & " " & $reqsplit[$i])
                If StringLeft($reqsplit[$i],3) = "GET" Or StringLeft($reqsplit[$i],4) = "POST" Or StringLeft($reqsplit[$i],7) = "CONNECT" And $modified_method = 0 Then
                        $reqsplit[$i] = StringReplace($reqsplit[$i],$host,"")
                        $reqsplit[$i] = StringReplace($reqsplit[$i],"http://","")
                        $reqsplit[$i] = StringReplace($reqsplit[$i],":443","")
                        $modified_method = 1
                EndIf 
                If StringInStr(Stringlower($reqsplit[$i]),"proxy-connection: keep-alive") And $modified_connection = 0 Then 
                    $reqsplit[$i] = "Connection: keep-alive"
                    $modified_connection = 1
                EndIf   
                If StringInStr(Stringlower($reqsplit[$i]),"accept-encoding") And $modified_encoding = 0 Then 
                    $reqsplit[$i] = $encoding
                    $modified_encoding = 1
                EndIf   
                _save(" -> to :" & $reqsplit[$i] & @CRLF)
            Next    
            $req = _ArrayToString($reqsplit, @CRLF , 1 , Ubound($reqsplit)-1)
        EndIf
        If GUICtrlRead($checkbox_debug_content) = 1 Then
            _save("] Request modified to:" & @CRLF)
            _save($req &@CRLF)
        EndIf
    EndIf
    Return $req
EndFunc

Enrico

please give me feedback if any host isn't working ( with hostname ) with proxy.

thanks

Edited by EnrMa

Share this post


Link to post
Share on other sites
lionel

it must error in the function: _request_modify($req,$host)

Share this post


Link to post
Share on other sites
EnrMa

I updated in prev. Post.

some POST methods aren't working. w3.org

POST is working now. I uploaded the script via the proxy so it modified the rows of the script too. This was the failure.

Enrico

Edited by EnrMa

Share this post


Link to post
Share on other sites
MariusN

Give credit where credit is due...brother, this is EXCELLENT work :mellow:

Share this post


Link to post
Share on other sites
Fire

EnrMa

Your script Fantastic !Thanks for share.


[size="5"] [/size]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.