Proxy and asynchronous socket in NetworkLib

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Proxy and asynchronous socket in NetworkLib

Post by RichAlgeni »

Beautiful mback2k! I will certainly dig into it!

Let me clarify just a bit, if another process does something well, like crypt library dlls, I would rather use those..., it's just one less thing I would need to debug. Since libraries like those are available, I would be in favor of Fred & Freak working on other issues..., but that's just my view.
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Proxy and asynchronous socket in NetworkLib

Post by RichAlgeni »

Does anyone see a problem with the two pieces of code presented in this thread?

Take a look at this:

http://www.purebasic.fr/english/viewtop ... =7&t=53376
yofu
New User
New User
Posts: 6
Joined: Tue Jun 13, 2017 8:27 am

Re: Proxy and asynchronous socket in NetworkLib

Post by yofu »

mback2k wrote:
RichAlgeni wrote:I'd have to disagree with https, or server side SSL because I am not a fan of reinventing the wheel. Besides, that would take up a tremendous amount of time for Fred and Freak.
Yes, it would require an amount of time from Fred and Freak, but it's not that hard since there is OpenSSL on Linux, native SecureTransport on Mac OS X and native Schannel on Windows. See my following Schannel include/DLL for Windows:

Code: Select all

; Author: mback2k
EnableExplicit

Import "secur32.lib"
  AcquireCredentialsHandleW(*pszPrincipal, pszPackage.p-unicode, fCredentialUse.l, *pvLogonID, *pAuthData, *pGetKeyFn, *pvGetKeyArgument, *phCredential, *ptsExpiry)
  FreeCredentialsHandle(*phCredential)
  InitializeSecurityContextW(*phCredential, *phContext, pszTargetName.p-unicode, fContextReq.l, Reserved1.l, TargetDataRep.l, *pInput, Reserved2.l, *phNewContext, *pOutput, *pfContextAttr, *ptsExpiry)
  QueryContextAttributesW(*phContext, ulAttribute.l, *pBuffer)
  DeleteSecurityContext(*phContext)
  DecryptMessage(*phContext, *pMessage, MessageSeqNo.l, *pfQOP)
  EncryptMessage(*phContext, fQOP.l, *pMessage, MessageSeqNo.l)
  FreeContextBuffer(*pvContextBuffer)
EndImport

Structure SCHANNEL_CRED
  dwVersion.l
  cCreds.l
  *paCred
  *hRootStore
  cMappers.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment1.b[4]
  CompilerEndIf
  *aphMappers
  cSupportedAlgs.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment2.b[4]
  CompilerEndIf
  *palgSupportedAlgs
  grbitEnabledProtocols.l
  dwMinimumCipherStrength.l
  dwMaximumCipherStrength.l
  dwSessionLifespan.l
  dwFlags.l
  dwCredFormat.l
EndStructure

Structure SecPkgInfo
  fCapabilities.l
  wVersion.w
  wRPCID.w
  cbMaxToken.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment.b[4]
  CompilerEndIf
  *Name
  *Comment
EndStructure

Structure SecPkgContext_StreamSizes
  cbHeader.l
  cbTrailer.l
  cbMaximumMessage.l
  cBuffers.l
  cbBlockSize.l
EndStructure

Structure SecBuffer
  cbBuffer.l
  BufferType.l
  *pvBuffer
EndStructure

Structure SecBufferDesc
  ulVersion.l
  cBuffers.l
  *pBuffers
EndStructure

Structure SecHandle
  *dwLower.Long
  *dwUpper.Long
EndStructure

Structure SecBuffers
  InBufferDesc.SecBufferDesc
  OutBufferDesc.SecBufferDesc
  InBuffers.SecBuffer[4]
  OutBuffers.SecBuffer[4]
EndStructure

Structure SecureConnection
  Magic.i
  Connection.i
  ServerName.s
  Port.i
  Protocol.i
  Flags.i
  PrevBytes.i
  PrevLength.i
  PrevSize.i
  Expiry.i
  CredHandle.SecHandle
  CtxtHandle.SecHandle
  StreamSizes.SecPkgContext_StreamSizes
EndStructure

Enumeration
  #SCHANNEL_CRED_VERSION = 4

  #SCH_CRED_NO_SERVERNAME_CHECK        = $00000004
  #SCH_CRED_MANUAL_CRED_VALIDATION     = $00000008
  #SCH_CRED_NO_DEFAULT_CREDS           = $00000010
  #SCH_CRED_AUTO_CRED_VALIDATION       = $00000020
  #SCH_CRED_REVOCATION_CHECK_END_CERT  = $00000100
  #SCH_CRED_REVOCATION_CHECK_CHAIN     = $00000200

  #SP_PROT_SSL2_CLIENT = $00000008
  #SP_PROT_SSL3_CLIENT = $00000020
  #SP_PROT_TLS1_CLIENT = $00000080
EndEnumeration

Enumeration
  #SECBUFFER_EMPTY                   = $00000000
  #SECBUFFER_VERSION                 = $00000000
  #SECBUFFER_DATA                    = $00000001
  #SECBUFFER_TOKEN                   = $00000002
  #SECBUFFER_PKG_PARAMS              = $00000003
  #SECBUFFER_MISSING                 = $00000004
  #SECBUFFER_EXTRA                   = $00000005
  #SECBUFFER_STREAM_TRAILER          = $00000006
  #SECBUFFER_STREAM_HEADER           = $00000007
  #SECBUFFER_NEGOTIATION_INFO        = $00000008
  #SECBUFFER_ALERT                   = $00000011

  #SECURITY_NATIVE_DREP              = $00000010
  #SECURITY_NETWORK_DREP             = $00000000

  #SECPKG_CRED_INBOUND               = $00000001
  #SECPKG_CRED_OUTBOUND              = $00000002
  #SECPKG_CRED_BOTH                  = $00000003

  #ISC_REQ_DELEGATE                  = $00000001
  #ISC_REQ_MUTUAL_AUTH               = $00000002
  #ISC_REQ_REPLAY_DETECT             = $00000004
  #ISC_REQ_SEQUENCE_DETECT           = $00000008
  #ISC_REQ_CONFIDENTIALITY           = $00000010
  #ISC_REQ_USE_SESSION_KEY           = $00000020
  #ISC_REQ_PROMPT_FOR_CREDS          = $00000040
  #ISC_REQ_USE_SUPPLIED_CREDS        = $00000080
  #ISC_REQ_ALLOCATE_MEMORY           = $00000100
  #ISC_REQ_USE_DCE_STYLE             = $00000200
  #ISC_REQ_DATAGRAM                  = $00000400
  #ISC_REQ_CONNECTION                = $00000800
  #ISC_REQ_CALL_LEVEL                = $00001000
  #ISC_REQ_EXTENDED_ERROR            = $00004000
  #ISC_REQ_STREAM                    = $00008000
  #ISC_REQ_INTEGRITY                 = $00010000
  #ISC_REQ_IDENTIFY                  = $00020000
  #ISC_REQ_NULL_SESSION              = $00040000

  #ASC_REQ_DELEGATE                  = $00000001
  #ASC_REQ_MUTUAL_AUTH               = $00000002
  #ASC_REQ_REPLAY_DETECT             = $00000004
  #ASC_REQ_SEQUENCE_DETECT           = $00000008
  #ASC_REQ_CONFIDENTIALITY           = $00000010
  #ASC_REQ_USE_SESSION_KEY           = $00000020
  #ASC_REQ_ALLOCATE_MEMORY           = $00000100
  #ASC_REQ_USE_DCE_STYLE             = $00000200
  #ASC_REQ_DATAGRAM                  = $00000400
  #ASC_REQ_CONNECTION                = $00000800
  #ASC_REQ_CALL_LEVEL                = $00001000
  #ASC_REQ_EXTENDED_ERROR            = $00008000
  #ASC_REQ_STREAM                    = $00010000
  #ASC_REQ_INTEGRITY                 = $00020000
  #ASC_REQ_LICENSING                 = $00040000
  #ASC_REQ_IDENTIFY                  = $00080000
  #ASC_REQ_ALLOW_NULL_SESSION        = $00100000

  #SECPKG_ATTR_SIZES                 = $00000000
  #SECPKG_ATTR_NAMES                 = $00000001
  #SECPKG_ATTR_LIFESPAN              = $00000002
  #SECPKG_ATTR_DCE_INFO              = $00000003
  #SECPKG_ATTR_STREAM_SIZES          = $00000004
  #SECPKG_ATTR_KEY_INFO              = $00000005
  #SECPKG_ATTR_AUTHORITY             = $00000006
  #SECPKG_ATTR_PROTO_INFO            = $00000007
  #SECPKG_ATTR_PASSWORD_EXPIRY       = $00000008
  #SECPKG_ATTR_SESSION_KEY           = $00000009
  #SECPKG_ATTR_PACKAGE_INFO          = $0000000A
  #SECPKG_ATTR_NATIVE_NAMES          = $0000000D

  #SEC_E_OK                          = $00000000
  #SEC_E_INSUFFICIENT_MEMORY         = $80090300
  #SEC_E_INVALID_HANDLE              = $80090301
  #SEC_E_UNSUPPORTED_FUNCTION        = $80090302
  #SEC_E_TARGET_UNKNOWN              = $80090303
  #SEC_E_INTERNAL_ERROR              = $80090304
  #SEC_E_SECPKG_NOT_FOUND            = $80090305
  #SEC_E_NOT_OWNER                   = $80090306
  #SEC_E_CANNOT_INSTALL              = $80090307
  #SEC_E_INVALID_TOKEN               = $80090308
  #SEC_E_CANNOT_PACK                 = $80090309
  #SEC_E_QOP_NOT_SUPPORTED           = $8009030A
  #SEC_E_NO_IMPERSONATION            = $8009030B
  #SEC_E_LOGON_DENIED                = $8009030C
  #SEC_E_UNKNOWN_CREDENTIALS         = $8009030D
  #SEC_E_NO_CREDENTIALS              = $8009030E
  #SEC_E_MESSAGE_ALTERED             = $8009030F
  #SEC_E_OUT_OF_SEQUENCE             = $80090310
  #SEC_E_NO_AUTHENTICATING_AUTHORITY = $80090311
  #SEC_I_CONTINUE_NEEDED             = $00090312
  #SEC_I_COMPLETE_NEEDED             = $00090313
  #SEC_I_COMPLETE_AND_CONTINUE       = $00090314
  #SEC_I_LOCAL_LOGON                 = $00090315
  #SEC_E_BAD_PKGID                   = $80090316
  #SEC_I_CONTEXT_EXPIRED             = $00090317
  #SEC_E_INCOMPLETE_MESSAGE          = $80090318
  #SEC_E_INCOMPLETE_CREDENTIALS      = $80090320
  #SEC_E_BUFFER_TOO_SMALL            = $80090321
  #SEC_I_INCOMPLETE_CREDENTIALS      = $00090320
  #SEC_I_RENEGOTIATE                 = $00090321
  #SEC_E_WRONG_PRINCIPAL             = $80090322

  #ERROR_NO_SUCH_DOMAIN              = $0000054B
  #ERROR_MORE_DATA                   = $000000EA
  #ERROR_NONE_MAPPED                 = $00000534
EndEnumeration

Procedure HandshakeSecureConnection(*SecureConnection.SecureConnection, Receive = #True)
  Protected *InBytes, InLength, InSize, ReceiveLength, OutFlags, Event, Retries, Status = #SEC_I_CONTINUE_NEEDED
  Protected Buffer.SecBuffers
  If *SecureConnection\PrevBytes And *SecureConnection\PrevLength And *SecureConnection\PrevSize
    *InBytes = AllocateMemory(*SecureConnection\PrevSize)
    InLength = *SecureConnection\PrevLength
    InSize = *SecureConnection\PrevSize
    CopyMemory(*SecureConnection\PrevBytes, *InBytes, *SecureConnection\PrevLength)
    MoveMemory(*SecureConnection\PrevBytes+*SecureConnection\PrevLength, *SecureConnection\PrevBytes, *SecureConnection\PrevLength)
    *SecureConnection\PrevLength = 0
  Else
    *InBytes = AllocateMemory(4096)
    InLength = 0
    InSize = 4096
  EndIf
  If *InBytes
    While Status = #SEC_I_CONTINUE_NEEDED Or Status = #SEC_E_INCOMPLETE_MESSAGE
      If InLength = 0 Or Status = #SEC_E_INCOMPLETE_MESSAGE
        If Receive
          If InSize-InLength < 1024
            *InBytes = ReAllocateMemory(*InBytes, InSize+4096)
            InSize + 4096
          EndIf
          Event = 0
          For Retries = 0 To 100
            Event = NetworkClientEvent(*SecureConnection\Connection)
            If Event = #PB_NetworkEvent_Data
              Break
            EndIf
            Delay(10)
          Next
          If Event = #PB_NetworkEvent_Data
            ReceiveLength = ReceiveNetworkData(*SecureConnection\Connection, *InBytes+InLength, InSize-InLength)
            If ReceiveLength > 0
              InLength + ReceiveLength
            EndIf
          EndIf
        Else
          Receive = #True
        EndIf
      EndIf
      Buffer\InBuffers[0]\pvBuffer    = *InBytes
      Buffer\InBuffers[0]\cbBuffer    = InLength
      Buffer\InBuffers[0]\BufferType  = #SECBUFFER_TOKEN
      Buffer\InBuffers[1]\pvBuffer    = #Null
      Buffer\InBuffers[1]\cbBuffer    = 0
      Buffer\InBuffers[1]\BufferType  = #SECBUFFER_EMPTY
      Buffer\InBufferDesc\cBuffers    = 2
      Buffer\InBufferDesc\pBuffers    = @Buffer\InBuffers
      Buffer\InBufferDesc\ulVersion   = #SECBUFFER_VERSION
      Buffer\OutBuffers[0]\pvBuffer   = #Null
      Buffer\OutBuffers[0]\cbBuffer   = 0;
      Buffer\OutBuffers[0]\BufferType = #SECBUFFER_TOKEN
      Buffer\OutBuffers[1]\pvBuffer   = #Null
      Buffer\OutBuffers[1]\cbBuffer   = 0
      Buffer\OutBuffers[1]\BufferType = #SECBUFFER_ALERT
      Buffer\OutBufferDesc\cBuffers   = 2
      Buffer\OutBufferDesc\pBuffers   = @Buffer\OutBuffers
      Buffer\OutBufferDesc\ulVersion  = #SECBUFFER_VERSION
      Status = InitializeSecurityContextW(@*SecureConnection\CredHandle, @*SecureConnection\CtxtHandle, *SecureConnection\ServerName, *SecureConnection\Flags, 0, #SECURITY_NATIVE_DREP, @Buffer\InBufferDesc, 0, #Null, @Buffer\OutBufferDesc, @OutFlags, @*SecureConnection\Expiry)
      If Status = #SEC_E_OK Or Status = #SEC_I_CONTINUE_NEEDED
        If Buffer\OutBuffers[0]\pvBuffer
          SendNetworkData(*SecureConnection\Connection, Buffer\OutBuffers[0]\pvBuffer, Buffer\OutBuffers[0]\cbBuffer)
          FreeContextBuffer(Buffer\OutBuffers[0]\pvBuffer)
        EndIf
      EndIf
      If Status = #SEC_E_INCOMPLETE_MESSAGE
        Continue
      EndIf
      If Status = #SEC_E_OK
        If Buffer\InBuffers[1]\BufferType = #SECBUFFER_EXTRA
          While *SecureConnection\PrevSize-*SecureConnection\PrevLength < Buffer\InBuffers[1]\cbBuffer
            *SecureConnection\PrevBytes = ReAllocateMemory(*SecureConnection\PrevBytes, *SecureConnection\PrevSize+4096)
            *SecureConnection\PrevSize + 4096
          Wend
          If CopyMemory(*InBytes+InLength-Buffer\InBuffers[1]\cbBuffer, *SecureConnection\PrevBytes+*SecureConnection\PrevLength, Buffer\InBuffers[1]\cbBuffer)
            *SecureConnection\PrevLength + Buffer\InBuffers[1]\cbBuffer
          EndIf
        EndIf
        Break
      EndIf
      If Status = #SEC_I_INCOMPLETE_CREDENTIALS
        Receive = #False
        Status = #SEC_I_CONTINUE_NEEDED
        Continue
      EndIf
      If Buffer\InBuffers[1]\BufferType = #SECBUFFER_EXTRA
        If MoveMemory(*InBytes+InLength-Buffer\InBuffers[1]\cbBuffer, *InBytes, Buffer\InBuffers[1]\cbBuffer)
          InLength = Buffer\InBuffers[1]\cbBuffer
        EndIf
      Else
        InLength = 0
      EndIf
    Wend
  EndIf
  ProcedureReturn *SecureConnection
EndProcedure

Procedure InitializeSecureConnection(*SecureConnection.SecureConnection)
  Protected SConnection, OutFlags
  Protected Buffer.SecBuffers
  Buffer\OutBuffers[0]\pvBuffer   = #Null
  Buffer\OutBuffers[0]\cbBuffer   = 0
  Buffer\OutBuffers[0]\BufferType = #SECBUFFER_TOKEN
  Buffer\OutBufferDesc\cBuffers   = 1
  Buffer\OutBufferDesc\pBuffers   = @Buffer\OutBuffers[0]
  Buffer\OutBufferDesc\ulVersion  = #SECBUFFER_VERSION
  If InitializeSecurityContextW(@*SecureConnection\CredHandle, #Null, *SecureConnection\ServerName, *SecureConnection\Flags, 0, #SECURITY_NATIVE_DREP, #Null, 0, @*SecureConnection\CtxtHandle, @Buffer\OutBufferDesc, @OutFlags, @*SecureConnection\Expiry) = #SEC_I_CONTINUE_NEEDED
    If Buffer\OutBuffers[0]\pvBuffer
      If SendNetworkData(*SecureConnection\Connection, Buffer\OutBuffers[0]\pvBuffer, Buffer\OutBuffers[0]\cbBuffer)
        SConnection = HandshakeSecureConnection(*SecureConnection)
        If SConnection
          ProcedureReturn SConnection
        EndIf
      EndIf
      FreeContextBuffer(Buffer\OutBuffers[0]\pvBuffer)
    EndIf
    If *SecureConnection\CtxtHandle
      DeleteSecurityContext(*SecureConnection\CtxtHandle)
    EndIf
  EndIf
EndProcedure

ProcedureDLL OpenSecureNetworkConnection(ServerName$, Port, Protocol = #SP_PROT_TLS1_CLIENT)
  Protected SConnection, SchannelCred.SCHANNEL_CRED, *SecureConnection.SecureConnection
  *SecureConnection = AllocateMemory(SizeOf(SecureConnection))
  If *SecureConnection
    *SecureConnection\Magic = 'SSPI'
    *SecureConnection\Connection = OpenNetworkConnection(ServerName$, Port, #PB_Network_TCP)
    If *SecureConnection\Connection
      SchannelCred\dwVersion = #SCHANNEL_CRED_VERSION
      SchannelCred\dwFlags = #SCH_CRED_NO_DEFAULT_CREDS | #SCH_CRED_AUTO_CRED_VALIDATION | #SCH_CRED_NO_SERVERNAME_CHECK | #SCH_CRED_REVOCATION_CHECK_END_CERT
      SchannelCred\grbitEnabledProtocols = Protocol
      If AcquireCredentialsHandleW(#Null, "Microsoft Unified Security Protocol Provider", #SECPKG_CRED_OUTBOUND, #Null, @SchannelCred, #Null, #Null, @*SecureConnection\CredHandle, @*SecureConnection\Expiry) = #SEC_E_OK
        *SecureConnection\ServerName = ServerName$
        *SecureConnection\Port = Port
        *SecureConnection\Protocol = SchannelCred\grbitEnabledProtocols
        *SecureConnection\Flags = #ISC_REQ_SEQUENCE_DETECT | #ISC_REQ_REPLAY_DETECT | #ISC_REQ_CONFIDENTIALITY | #ISC_REQ_EXTENDED_ERROR | #ISC_REQ_ALLOCATE_MEMORY | #ISC_REQ_STREAM
        *SecureConnection\PrevBytes = AllocateMemory(4096)
        *SecureConnection\PrevSize = 4096
        SConnection = InitializeSecureConnection(*SecureConnection)
        If SConnection
          ProcedureReturn SConnection
        EndIf
        If *SecureConnection\CredHandle
          FreeCredentialsHandle(*SecureConnection\CredHandle)
        EndIf
        If *SecureConnection\PrevBytes
          FreeMemory(*SecureConnection\PrevBytes)
        EndIf
      EndIf
      CloseNetworkConnection(*SecureConnection\Connection)
    EndIf
  EndIf
EndProcedure

ProcedureDLL CloseSecureNetworkConnection(*SecureConnection.SecureConnection)
  If *SecureConnection And *SecureConnection\Magic = 'SSPI'
    FreeCredentialsHandle(*SecureConnection\CredHandle)
    DeleteSecurityContext(*SecureConnection\CtxtHandle)
    CloseNetworkConnection(*SecureConnection\Connection)
    FreeMemory(*SecureConnection\PrevBytes)
    FreeMemory(*SecureConnection)
  EndIf
EndProcedure

ProcedureDLL ReceiveSecureNetworkData(*SecureConnection.SecureConnection, *DataBuffer, DataBufferLength)
  Protected *InBytes, InLength, InSize, ReceiveLength, OutFlags, Result, Index, Event, Retries, Receive = #True, Status = #SEC_I_CONTINUE_NEEDED
  Protected Buffer.SecBuffers
  If *SecureConnection And *SecureConnection\Magic = 'SSPI' And *DataBuffer And DataBufferLength > 0
    If *SecureConnection\PrevBytes And *SecureConnection\PrevLength And *SecureConnection\PrevSize
      *InBytes = AllocateMemory(*SecureConnection\PrevSize)
      InLength = *SecureConnection\PrevLength
      InSize = *SecureConnection\PrevSize
      CopyMemory(*SecureConnection\PrevBytes, *InBytes, *SecureConnection\PrevLength)
      MoveMemory(*SecureConnection\PrevBytes+*SecureConnection\PrevLength, *SecureConnection\PrevBytes, *SecureConnection\PrevLength)
      *SecureConnection\PrevLength = 0
    Else
      *InBytes = AllocateMemory(4096)
      InLength = 0
      InSize = 4096
    EndIf
    If *InBytes
      While Status = #SEC_I_CONTINUE_NEEDED Or Status = #SEC_E_INCOMPLETE_MESSAGE
        If InLength = 0 Or Status = #SEC_E_INCOMPLETE_MESSAGE
          If InSize-InLength < 1024
            *InBytes = ReAllocateMemory(*InBytes, InSize+4096)
            InSize + 4096
          EndIf
          Event = 0
          For Retries = 0 To 100
            Event = NetworkClientEvent(*SecureConnection\Connection)
            If Event = #PB_NetworkEvent_Data
              Break
            EndIf
            Delay(10)
          Next
          If Event = #PB_NetworkEvent_Data
            ReceiveLength = ReceiveNetworkData(*SecureConnection\Connection, *InBytes+InLength, InSize-InLength)
            If ReceiveLength > 0
              InLength + ReceiveLength
            EndIf
          EndIf
        EndIf
        Buffer\InBuffers[0]\pvBuffer     = *InBytes
        Buffer\InBuffers[0]\cbBuffer     = InLength
        Buffer\InBuffers[0]\BufferType   = #SECBUFFER_DATA
        For Index = 1 To 3
          Buffer\InBuffers[Index]\pvBuffer     = #Null
          Buffer\InBuffers[Index]\cbBuffer     = 0
          Buffer\InBuffers[Index]\BufferType   = #SECBUFFER_EMPTY
        Next
        Buffer\InBufferDesc\ulVersion    = #SECBUFFER_VERSION
        Buffer\InBufferDesc\cBuffers     = 4
        Buffer\InBufferDesc\pBuffers     = @Buffer\InBuffers[0]
        Status = DecryptMessage(@*SecureConnection\CtxtHandle, @Buffer\InBufferDesc, 0, #Null)
        If Status = #SEC_E_OK Or Status = #SEC_I_RENEGOTIATE
          If Buffer\InBuffers[1]\BufferType = #SECBUFFER_DATA
            If Result+Buffer\InBuffers[1]\cbBuffer <= DataBufferLength
              If CopyMemory(Buffer\InBuffers[1]\pvBuffer, *DataBuffer+Result, Buffer\InBuffers[1]\cbBuffer)
                Result + Buffer\InBuffers[1]\cbBuffer
              EndIf
            EndIf
          EndIf
          If Result = 0
            Status = #SEC_I_CONTINUE_NEEDED
          EndIf
        EndIf
        If Status = #SEC_E_INCOMPLETE_MESSAGE
          Continue
        EndIf
        If Status = #SEC_E_OK Or Status = #SEC_I_CONTEXT_EXPIRED
          If Buffer\InBuffers[3]\BufferType = #SECBUFFER_EXTRA
            While *SecureConnection\PrevSize-*SecureConnection\PrevLength < Buffer\InBuffers[3]\cbBuffer
              *SecureConnection\PrevBytes = ReAllocateMemory(*SecureConnection\PrevBytes, *SecureConnection\PrevSize+4096)
              *SecureConnection\PrevSize + 4096
            Wend
            If CopyMemory(*InBytes+InLength-Buffer\InBuffers[3]\cbBuffer, *SecureConnection\PrevBytes+*SecureConnection\PrevLength, Buffer\InBuffers[3]\cbBuffer)
              *SecureConnection\PrevLength + Buffer\InBuffers[3]\cbBuffer
            EndIf
          EndIf
          Break
        EndIf
        If Status = #SEC_I_RENEGOTIATE
          HandshakeSecureConnection(*SecureConnection.SecureConnection, #False)
        EndIf
        If Buffer\InBuffers[3]\BufferType = #SECBUFFER_EXTRA
          If MoveMemory(*InBytes+InLength-Buffer\InBuffers[3]\cbBuffer, *InBytes, Buffer\InBuffers[3]\cbBuffer)
            InLength = Buffer\InBuffers[3]\cbBuffer
          EndIf
        Else
          InLength = 0
        EndIf
      Wend
      ProcedureReturn Result
    EndIf
  EndIf
  ProcedureReturn -1
EndProcedure

ProcedureDLL SendSecureNetworkData(*SecureConnection.SecureConnection, *MemoryBuffer, Length)
  Protected *DataBuffer, Buffer.SecBuffers
  If *SecureConnection And *SecureConnection\Magic = 'SSPI' And *MemoryBuffer And Length > 0
    If Not *SecureConnection\StreamSizes\cbMaximumMessage
      QueryContextAttributesW(*SecureConnection\CtxtHandle, #SECPKG_ATTR_STREAM_SIZES, @*SecureConnection\StreamSizes)
    EndIf
    If Length <= *SecureConnection\StreamSizes\cbMaximumMessage
      *DataBuffer = AllocateMemory(*SecureConnection\StreamSizes\cbHeader+Length+*SecureConnection\StreamSizes\cbTrailer)
      If *DataBuffer
        Buffer\OutBuffers[0]\pvBuffer     = *DataBuffer
        Buffer\OutBuffers[0]\cbBuffer     = *SecureConnection\StreamSizes\cbHeader
        Buffer\OutBuffers[0]\BufferType   = #SECBUFFER_STREAM_HEADER
        Buffer\OutBuffers[1]\pvBuffer     = *DataBuffer+*SecureConnection\StreamSizes\cbHeader
        Buffer\OutBuffers[1]\cbBuffer     = Length
        Buffer\OutBuffers[1]\BufferType   = #SECBUFFER_DATA
        Buffer\OutBuffers[2]\pvBuffer     = *DataBuffer+*SecureConnection\StreamSizes\cbHeader+Length
        Buffer\OutBuffers[2]\cbBuffer     = *SecureConnection\StreamSizes\cbTrailer
        Buffer\OutBuffers[2]\BufferType   = #SECBUFFER_STREAM_TRAILER
        Buffer\OutBuffers[3]\pvBuffer     = #Null
        Buffer\OutBuffers[3]\cbBuffer     = 0
        Buffer\OutBuffers[3]\BufferType   = #SECBUFFER_EMPTY
        Buffer\OutBufferDesc\ulVersion    = #SECBUFFER_VERSION
        Buffer\OutBufferDesc\cBuffers     = 4
        Buffer\OutBufferDesc\pBuffers     = @Buffer\OutBuffers[0]
        If CopyMemory(*MemoryBuffer, Buffer\OutBuffers[1]\pvBuffer, Length)
          If EncryptMessage(*SecureConnection\CtxtHandle, 0, @Buffer\OutBufferDesc, 0) = #SEC_E_OK
            SendNetworkData(*SecureConnection\Connection, *DataBuffer, Buffer\OutBuffers[0]\cbBuffer+Buffer\OutBuffers[1]\cbBuffer+Buffer\OutBuffers[2]\cbBuffer)
            FreeMemory(*DataBuffer)
            ProcedureReturn Length
          EndIf
        EndIf
        FreeMemory(*DataBuffer)
      EndIf
    EndIf
  EndIf
  ProcedureReturn -1
EndProcedure

ProcedureDLL GetSecureConnectionHandle(*SecureConnection.SecureConnection)
  If *SecureConnection And *SecureConnection\Magic = 'SSPI'
    ProcedureReturn *SecureConnection\Connection
  EndIf
EndProcedure
Why SendSecureNetworkData do'not work?

Code: Select all

*SecureConnection.SecureConnection
*SecureConnection = OpenSecureNetworkConnection("google.com", 443) 
Result = SendSecureNetworkData(*SecureConnection, @"GET", 3) 
Debug Result  ;Returns -1
Help me plz
SergeyA
New User
New User
Posts: 8
Joined: Sun Jan 20, 2013 9:09 am

Re: Proxy and asynchronous socket in NetworkLib

Post by SergeyA »

+1
Post Reply