PureSmtp via Proxy

Für allgemeine Fragen zur Programmierung mit PureBasic.
MenschMarkus
Beiträge: 229
Registriert: 30.04.2009 21:21
Computerausstattung: i5-2300 (2.8 Ghz) Win10 -64bit / PB 5.73 LTS

PureSmtp via Proxy

Beitrag von MenschMarkus »

Hi zusammen,

versuche gerade PureSMTP über eine Proxy Verbindung zu nutzen. Leider ohne Erfolg. Bereits bei "PureSMTP_OpenSMTPConnection(MySMTPServer, MySMTPPort)" scheitere ich. Bei direkter Anbindung an das INet funktioniert die e-mail versendung.

Die Initialisierung als HTTP oder Socks 4/5 über Proxy funktioniert ebenfalls.

Als Proxy verwende ich Jana 2 (übrigens sehr empfehlenswert, da einfach zu verwenden und zu konfigurieren :D (http://www.janaserver.de))
Nach Umstellung des Standardbrowsers auf die IP des Proxies nebst Port funzt das INet

Hat jemand ne Idee wie ich PureSMTP über Proxy zu Laufen kriege?

Thanks folks for useful reply only 8)

Hier einmal die Verbindung zum Proxy (Hab ich im PB Forum gefunden) nebst der Mailroutine

Code: Alles auswählen

Procedure.l Proxy_Connect( proxy_ip.s, proxy_port.l, ip_to_connect.s, port_to_connect.l, type.l, username.s, userpass.s, timeout.l )
    
  ;proxy_ip        = IP or URL of the Proxy-Server
  ;proxy_port      = Port of the Proxy-Server
  ;ip_to_connect   = IP or URL of where you want to connect through proxy. ATTENTION:
  ;  SOCKS4 only supports IP in IPv4-format! You have to get the IP first before using this on urls, otherwise it will fail!
  ;port_to_connect = Port of where you want to connect through proxy
  ;type            = 0 -> http-proxy
  ;type            = 1 -> socks4-proxy
  ;type            = 2 -> socks5-proxy
  ;If no authorization is needed set username and userpass = ""
  ;timeout         -> Time after connection-trial will time out (in SECONDS)
  ;Return-Value    = 0 -> error ; Return-Value > 0 -> ConnectionID
  
  *buffer = AllocateMemory(1024)
  If *buffer = 0
    ProcedureReturn #False
  EndIf
  
  netid.l = OpenNetworkConnection(proxy_ip, proxy_port)
  
  If netid = 0
    FreeMemory(*buffer)
    ProcedureReturn #False
  EndIf

  Select type
  
    Case 0
      ;====================
      ;-HTTP - Proxy
      ;====================
      ;Based on Num3's http-proxy-snippet , THX! ->
      ;http://jconserv.net/purebasic/viewtopic.php?t=10327
  ;{    
      text$ = "CONNECT " + ip_to_connect + ":" + Str(port_to_connect) + " HTTP/1.0" + #CRLF$
      
      If username And userpass
        user$ = username + ":" + userpass
        length.l = Len(user$) * 2
        If length < 64
          length = 64
        EndIf
        Base64Encoder(@user$, Len(user$), *buffer, length)
        encoded$ = PeekS(*buffer)
        text$ + "Authorization: Basic " + encoded$ + #CRLF$
        text$ + "Proxy-Authorization: Basic " + encoded$ + #CRLF$
      EndIf
      text$ + #CRLF$

      SendNetworkData(netid, @text$, Len(text$))
      check_timeout.l = ElapsedMilliseconds() + ( timeout * 1000 )
      Repeat
        Delay(10)
        If NetworkClientEvent(netid) = 2
          Content$ = Space(14500)
          length.l = ReceiveNetworkData(netid, @Content$, 14500)
          While length = 14500
            ;Clear Input-Buffer
            length = ReceiveNetworkData(netid, *buffer, 14500)
          Wend
          Break
        EndIf
      Until check_timeout < ElapsedMilliseconds()
      Result.l = 0
      For i = 1 To CountString(Content$, Chr(10))
        a$ = Trim(StringField(Content$, i, Chr(10)))
        If Left(a$, 7) = "HTTP/1."
          Result = Val(StringField(Content$, 2, Chr(32)))
          Break
        EndIf
      Next i
      If check_timeout < ElapsedMilliseconds() Or Result <> 200
        FreeMemory(*buffer)
        CloseNetworkConnection(netid)
        ProcedureReturn #False
      EndIf
      FreeMemory(*buffer)
      ProcedureReturn netid
;}
    Case 1
      ;====================
      ;-Socks4 - Proxy
      ;====================
;{      
      ;Socks4 only supports IPv4 !
      ;You have to do a DNS-Lookup before using this on urls, otherwise it will fail!
      If IsIP(ip_to_connect) <> 1
        FreeMemory(*buffer)
        CloseNetworkConnection(netid)
        ProcedureReturn #False
      EndIf
      ;-Phase 1 SOCK4
      ;Send Request
      PokeB(*buffer, 4)
      PokeB(*buffer + 1, 1)
      hi.l = Int(port_to_connect / 256)
      lo.l = port_to_connect - (256 * hi)
      PokeB(*buffer + 2, hi)
      PokeB(*buffer + 3, lo)
      For i = 1 To 4
        PokeB(*buffer + 3 + i, Val(StringField(ip_to_connect, i, ".")) & 255)
      Next i
      PokeS(*buffer + 8, username)
      length.l = 9 + Len(username)
      SendNetworkData(netid, *buffer, length)
      ;Check if connection is established
      check_timeout.l = ElapsedMilliseconds() + ( timeout * 1000 )
      Repeat
        Delay(10)
        If NetworkClientEvent(netid) = 2
          ReceiveNetworkData(netid, *buffer, 1024)
          ver.l = PeekB(*buffer) & 255
          CD.l = PeekB(*buffer + 1) & 255
          port.l = (PeekB(*buffer + 2) & 255) * 256
          port + (PeekB(*buffer + 3) & 255)
          ip.s = Str(PeekB(*buffer + 4) & 255) + "." + Str(PeekB(*buffer + 5) & 255) + "."
          ip + Str(PeekB(*buffer + 6) & 255) + "." + Str(PeekB(*buffer + 7) & 255)
          Break
        EndIf
      Until check_timeout < ElapsedMilliseconds()
      If check_timeout < ElapsedMilliseconds() Or ver <> 0 Or CD <> 90
        FreeMemory(*buffer)
        CloseNetworkConnection(netid)
        ProcedureReturn #False
      EndIf
      ;IP and Port should be the same like ip_to_connect/port_to_connect and is just for information
      Debug "Connected to IP:" + ip
      Debug "Connected to Port:" + Str(port)
      FreeMemory(*buffer)
      ProcedureReturn netid
;}
    Case 2        
        ;====================
      ;-Socks5 - Proxy
      ;====================
;{
      ;-Phase 1 SOCK5
      ;Send wished method
      If username = "" And userpass = ""
        length.l = 3
        PokeB(*buffer, 5)
        PokeB(*buffer + 1, 1)
        PokeB(*buffer + 2, 0)
      Else
        length.l = 4
        PokeB(*buffer, 5)
        PokeB(*buffer + 1, 2)
        PokeB(*buffer + 2, 0)
        PokeB(*buffer + 3, 2) 
      EndIf
      SendNetworkData(netid, *buffer, length)
      ;Check if method is allowed
      check_timeout.l = ElapsedMilliseconds() + ( timeout * 1000 )
      Repeat
        Delay(10)
        If NetworkClientEvent(netid) = 2
          ReceiveNetworkData(netid, *buffer, 2)
          ver.l = PeekB(*buffer) & 255
          method.l = PeekB(*buffer + 1) & 255
          Break
        EndIf
      Until check_timeout < ElapsedMilliseconds()
      If check_timeout < ElapsedMilliseconds() Or ver <> 5 Or method = 255
        FreeMemory(*buffer)
        CloseNetworkConnection(netid)
        ProcedureReturn #False
      EndIf
      If method = 2
        ;-Phase 2 SOCK5
        ;Send Username/Password (if allowed)
        PokeB(*buffer, 1)
        PokeB(*buffer + 1, Len(username))
        PokeS(*buffer + 2, username)
        k = 2 + Len(username)
        PokeB(*buffer + k, Len(userpass))
        PokeS(*buffer + k + 1, userpass)
        SendNetworkData(netid, *buffer, Len(userpass) + 1 + k)
        ;Check if Username/Password is accepted
        check_timeout.l = ElapsedMilliseconds() + ( timeout * 1000 )
        Repeat
          Delay(10)
          If NetworkClientEvent(netid) = 2
            ReceiveNetworkData(netid, *buffer, 2)
            passver.l = PeekB(*buffer) & 255
            status.l = PeekB(*buffer + 1) & 255
            Break
          EndIf
        Until check_timeout < ElapsedMilliseconds()
        If check_timeout < ElapsedMilliseconds() Or passver <> 1 Or status <> 0
          FreeMemory(*buffer)
          CloseNetworkConnection(netid)
          ProcedureReturn #False
        EndIf
      EndIf
      ;-Phase 3 SOCK5
      ;Send Connect-Request
      PokeB(*buffer, 5)
      PokeB(*buffer + 1, 1)
      PokeB(*buffer + 2, 0)
      Select IsIP( ip_to_connect )
        Case 0
          PokeB(*buffer + 3, 3)
          PokeB(*buffer + 4, Len(ip_to_connect))
          For i = 1 To Len(ip_to_connect)
            PokeB(*buffer + 4 + i, Asc(Mid(ip_to_connect, i, 1)))
          Next i
          cont.l = 4 + i
        Case 1
          PokeB(*buffer + 3, 1)
          For i = 1 To 4
            PokeB(*buffer + 3 + i, Val(StringField(ip_to_connect, i, ".")) & 255)
          Next i
          cont.l = 8
        Case 2
          PokeB(*buffer + 3, 4)
          For i = 1 To 6
            PokeB(*buffer + 3 + i, Val(StringField(ip_to_connect, i, ".")) & 255)
          Next i
          cont.l = 10
      EndSelect
      hi.l = Int(port_to_connect / 256)
      lo.l = port_to_connect - (256 * hi)
      PokeB(*buffer + cont, hi)
      PokeB(*buffer + cont + 1, lo)
      SendNetworkData(netid, *buffer, cont + 2)
      ;Now Check the reply
      check_timeout.l = ElapsedMilliseconds() + ( timeout * 1000 )
      Repeat
        Delay(10)
        If NetworkClientEvent(netid) = 2
          length.l = ReceiveNetworkData(netid, *buffer, 1024)
          ver.l = PeekB(*buffer) & 255
          reply.l = PeekB(*buffer + 1) & 255
          reserved.l = PeekB(*buffer + 2) & 255
          atyp.l = PeekB(*buffer + 3) & 255
          Break
        EndIf
      Until check_timeout < ElapsedMilliseconds()
      If check_timeout < ElapsedMilliseconds() Or ver <> 5 Or reply <> 0 Or reserved <> 0
        FreeMemory(*buffer)
        CloseNetworkConnection(netid)
        ProcedureReturn #False
      EndIf
      Select atyp
        Case 1
          ;IPv4
          ip.s = Str(PeekB(*buffer + 4) & 255) + "." + Str(PeekB(*buffer + 5) & 255) + "."
          ip + Str(PeekB(*buffer + 6) & 255) + "." + Str(PeekB(*buffer + 7) & 255)
          port.l = (PeekB(*buffer + 8) & 255) * 256
          port + (PeekB(*buffer + 9) & 255)
        Case 3
          ;Name
          ip.s = ""
          For i = 1 To (PeekB(*buffer + 4) & 255)
            ip + Chr(PeekB(*buffer + 4 + i) & 255)
          Next i
          port.l = (PeekB(*buffer + 4 + i) & 255) * 256
          port + (PeekB(*buffer + 5 + i) & 255)
        Case 4
          ;IPv6
          ip.s = Str(PeekB(*buffer + 4) & 255) + "." + Str(PeekB(*buffer + 5) & 255) + "."
          ip + Str(PeekB(*buffer + 6) & 255) + "." + Str(PeekB(*buffer + 7) & 255)  + "."
          ip + Str(PeekB(*buffer + 8) & 255) + "." + Str(PeekB(*buffer + 9) & 255)
          port.l = (PeekB(*buffer + 10) & 255) * 256
          port + (PeekB(*buffer + 11) & 255)
          
     EndSelect
;}     
     ;Following IP and Port is just for information... 
      ;this is proxy-internal and not necessarily the same as ip_to_connect/port_to_connect
      Debug "Internal Proxy-IP:" + ip
      Debug "Internal Proxy-Port:" + Str(port)
      FreeMemory(*buffer)
      ProcedureReturn netid

  EndSelect

EndProcedure

;\\\\\\\\\\\\\\\\\\\\\\\\\\\
; Mail Source
;\\\\\\\\\\\\\\\\\\\\\\\\\\\

Procedure mailme()
     MySMTPServer.s = "MySmtpServer"
     MySMTPPort.l = 25
     PureSMTP_SkipInitNetwork(NetID.l)    ;wurde vorab schon initialisiert !!
     PureSMTP_SetXMailer("MyXMailer")
     If PureSMTP_OpenSMTPConnection(MySMTPServer, MySMTPPort) = 1
         Subject.s = "Proxy TestMail"
         MailTo.s = "Destination@mailadress"
         MailFrom.s = "Source@mailaddress"
         MsgBody.s = "My Mail Body "
         Attachments.s = ""
         UserName.s = "UserName"
         Password.s = "Password"
         Status.l = PureSMTP_SendMail(MailTo, MailFrom, Subject, MsgBody, Attachments, UserName, Password)
         PureSMTP_CloseSMTPConnection()
     Else
         MessageRequester(ERROR","SMTP Connection Failed !" + Chr(13) + PureSMTP_GetLastServerMessage(),#MB_ICONERROR)
     EndIf
    
EndProcedure
Wissen schadet nur dem, der es nicht hat !