<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Отправка почты через соккеты, TLS и Schannel]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=17650</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17650&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Отправка почты через соккеты, TLS и Schannel».]]></description>
		<lastBuildDate>Sun, 12 Mar 2023 01:38:50 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[AHK: Отправка почты через соккеты, TLS и Schannel]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=157087#p157087</link>
			<description><![CDATA[<p>Попробовал отправить почту через соккеты с помощью Secure Channel API.<br />Хорошая статья по теме:<br /><a href="https://web.archive.org/web/20201015234913/https://sites.google.com/site/libfcgi2/tls-with-schannel">https://web.archive.org/web/20201015234 … h-schannel</a><br /></p><div class="codebox"><pre><code>server := &quot;smtp.gmail.com&quot;
port := 465   ; can be 587
login := &quot;YourEmail@gmail.com&quot;
password := &quot;YourPassword&quot;
MailTo := &quot;MailTo@gmail.com&quot;
Subject := &quot;Test from Malcev&quot;
EmailText := &quot;This is a test message&quot;

Base64 := Base64(login, password)
data = 
(
EHLO Malcev \r\n
AUTH PLAIN %Base64% \r\n
MAIL FROM:&lt;%login%&gt; \r\n
RCPT TO:&lt;%MailTo%&gt; \r\n
DATA \r\n
Subject: %Subject% \r\n\r\n %EmailText% \r\n.\r\n
QUIT \r\n
)

dwSSPIFlags := (ISC_REQ_SEQUENCE_DETECT := 8) | (ISC_REQ_REPLAY_DETECT := 4) | (ISC_REQ_CONFIDENTIALITY := 16) | (ISC_RET_EXTENDED_ERROR := 16384) | (ISC_REQ_ALLOCATE_MEMORY := 256) | (ISC_REQ_STREAM := 32768)
SEC_E_OK := 0
SEC_I_CONTINUE_NEEDED := 0x00090312
SEC_E_INCOMPLETE_MESSAGE := 0x80090318
SEC_I_INCOMPLETE_CREDENTIALS := 0x00090320
SEC_I_CONTEXT_EXPIRED := 0x00090317
SEC_I_RENEGOTIATE := 0x00090321
SECBUFFER_DATA := 1
SECBUFFER_TOKEN := 2
SECBUFFER_EXTRA := 5
SECBUFFER_STREAM_TRAILER := 6
SECBUFFER_STREAM_HEADER := 7
IO_BUFFER_SIZE := 65536

DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;ws2_32.dll&quot;, &quot;ptr&quot;)
VarSetCapacity(WSADATA, 394 + (A_PtrSize - 2) + A_PtrSize, 0)
DllCall(&quot;ws2_32\WSAStartup&quot;, &quot;ushort&quot;, 0x0202, &quot;ptr&quot;, &amp;WSADATA)
socket := DllCall(&quot;ws2_32\socket&quot;, &quot;int&quot;, PF_INET := 2, &quot;int&quot;, SOCK_STREAM := 1, &quot;int&quot;, 0)
sin_port := DllCall(&quot;ws2_32\htons&quot;, &quot;ushort&quot;, port, &quot;ushort&quot;)
VarSetCapacity(addrinfo, 16+4*A_PtrSize, 0)
NumPut(AF_INET := 2, addrinfo, 4, &quot;int&quot;)
NumPut(SOCK_STREAM := 1, addrinfo, 8, &quot;int&quot;)
NumPut(IPPROTO_TCP := 6, addrinfo, 12, &quot;int&quot;)
DllCall(&quot;ws2_32\getaddrinfo&quot;, &quot;astr&quot;, server, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;addrinfo, &quot;ptr*&quot;, addrinfoOut)
addrinfoOut_ai_addr := NumGet(addrinfoOut+0, 16+2*A_PtrSize, &quot;ptr&quot;)
sin_addr := NumGet(addrinfoOut_ai_addr+0, 4, &quot;uint&quot;)
VarSetCapacity(sockaddr_in, 16, 0)
NumPut(AF_INET := 2, sockaddr_in, 0, &quot;short&quot;)   ; sin_family
NumPut(sin_port, sockaddr_in, 2, &quot;ushort&quot;)   ; sin_port
NumPut(sin_addr, sockaddr_in, 4, &quot;uint&quot;)   ; sin_addr
DllCall(&quot;ws2_32\connect&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;sockaddr_in, &quot;int&quot;, 16)
if (port != 465)
{
   ReceivedDataSize := 4096
   VarSetCapacity(ReceivedData, ReceivedDataSize, 0)
   DllCall(&quot;ws2_32\recv&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;ReceivedData, &quot;int&quot;, ReceivedDataSize, &quot;int&quot;, 0)
   msgbox % strget(&amp;ReceivedData, &quot;utf-8&quot;)
   string := &quot;EHLO Malcev`r`n&quot;
   DllCall(&quot;ws2_32\send&quot;, &quot;int&quot;, socket, &quot;astr&quot;, string, &quot;int&quot;, strlen(string), &quot;int&quot;, 0)
   VarSetCapacity(ReceivedData, ReceivedDataSize, 0)
   DllCall(&quot;ws2_32\recv&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;ReceivedData, &quot;int&quot;, ReceivedDataSize, &quot;int&quot;, 0)
   msgbox % strget(&amp;ReceivedData, &quot;utf-8&quot;)
   string := &quot;starttls`r`n&quot;
   DllCall(&quot;ws2_32\send&quot;, &quot;int&quot;, socket, &quot;astr&quot;, string, &quot;int&quot;, strlen(string), &quot;int&quot;, 0)
   VarSetCapacity(ReceivedData, ReceivedDataSize, 0)
   DllCall(&quot;ws2_32\recv&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;ReceivedData, &quot;int&quot;, ReceivedDataSize, &quot;int&quot;, 0)
   msgbox % strget(&amp;ReceivedData, &quot;utf-8&quot;)
}

DllCall(&quot;LoadLibrary&quot;,&quot;str&quot;, &quot;Secur32.dll&quot;, &quot;ptr&quot;)
g_pSSPI := DllCall(&quot;Secur32\InitSecurityInterface&quot;, &quot;ptr&quot;)
VarSetCapacity(hCreds, 2*A_PtrSize, 0)
VarSetCapacity(SchannelCred, A_PtrSize*6+40, 0)
NumPut(SCHANNEL_CRED_VERSION := 4, SchannelCred, 0, &quot;uint&quot;)   ; dwVersion
NumPut(SP_PROT_TLS1_2_CLIENT := 0x800, SchannelCred, A_PtrSize*6+16, &quot;uint&quot;)   ; grbitEnabledProtocols
NumPut(SCH_CRED_NO_DEFAULT_CREDS := 0x00000010, SchannelCred, A_PtrSize*6+32, &quot;uint&quot;)   ; dwFlags
DllCall(NumGet(g_pSSPI+3*A_PtrSize), &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;(UNISP_NAME := &quot;Microsoft Unified Security Protocol Provider&quot;), &quot;uint&quot;, SECPKG_CRED_OUTBOUND := 0x2, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;SchannelCred, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;hCreds, &quot;int64*&quot;, tsExpiry)   ; AcquireCredentialsHandle
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, &quot;uint&quot;)   ; BufferType
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, &quot;uint&quot;)   ; cBuffers
NumPut(&amp;OutBuffers, OutBuffer, 8, &quot;ptr&quot;)   ; pBuffers
VarSetCapacity(hContext, 2*A_PtrSize, 0)
scRet := DllCall(NumGet(g_pSSPI+6*A_PtrSize), &quot;ptr&quot;, &amp;hCreds, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;server, &quot;uint&quot;, dwSSPIFlags, &quot;uint&quot;, 0, &quot;uint&quot;, SECURITY_NATIVE_DREP := 16, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, &amp;hContext, &quot;ptr&quot;, &amp;OutBuffer, &quot;uint*&quot;, dwSSPIOutFlags, &quot;int64*&quot;, tsExpiry, &quot;uint&quot;)   ; InitializeSecurityContext
if (scRet != SEC_I_CONTINUE_NEEDED)
{
   msgbox InitializeSecurityContext first time error
   exitapp
}
OutBuffers0_cbBuffer := NumGet(OutBuffers, 0, &quot;uint&quot;)
OutBuffers0_pvBuffer := NumGet(OutBuffers, 8, &quot;ptr&quot;)
if (OutBuffers0_cbBuffer != 0) and (OutBuffers0_pvBuffer != 0)
{
   cbData := DllCall(&quot;ws2_32\send&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, OutBuffers0_pvBuffer, &quot;int&quot;, OutBuffers0_cbBuffer, &quot;int&quot;, 0)
   if (cbData &lt;= 0)
   {
      msgbox ws2_32\send first time error
      exitapp
   }
   DllCall(NumGet(g_pSSPI+16*A_PtrSize), &quot;ptr&quot;, OutBuffers0_pvBuffer)   ; FreeContextBuffer
}
fDoRead := 1
GoSub HandshakeLoop
VarSetCapacity(Sizes, 20, 0)
scRet := DllCall(NumGet(g_pSSPI+11*A_PtrSize), &quot;ptr&quot;, &amp;hContext, &quot;uint&quot;, SECPKG_ATTR_STREAM_SIZES := 4, &quot;ptr&quot;, &amp;Sizes, &quot;uint&quot;)   ; QueryContextAttributes
if (scRet != SEC_E_OK)
{
   msgbox QueryContextAttributes error
   exitapp
}
Sizes_cbHeader := NumGet(Sizes, 0, &quot;uint&quot;)
Sizes_cbTrailer := NumGet(Sizes, 4, &quot;uint&quot;)
Sizes_cbMaximumMessage := NumGet(Sizes, 8, &quot;uint&quot;)
cbIoBufferLength := Sizes_cbHeader + Sizes_cbMaximumMessage + Sizes_cbTrailer
VarSetCapacity(pbIoBuffer, cbIoBufferLength, 0)
if (port = 465)
   GoSub ReadDecrypt
Loop, parse, data, `n, `r
{
   sendData := StrReplace(A_LoopField, &quot;\r\n&quot;, &quot;`r`n&quot;)
   GoSub EncryptSend
   msgbox % DecryptedData
}

;DisconnectFromServer
VarSetCapacity(SCHANNEL_SHUTDOWN, 4, 0)
NumPut(1, SCHANNEL_SHUTDOWN, 0, &quot;int&quot;)
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(4, OutBuffers, 0, &quot;uint&quot;)   ; cbBuffer
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, &quot;uint&quot;)   ; BufferType
NumPut(&amp;SCHANNEL_SHUTDOWN, OutBuffers, 8, &quot;ptr&quot;)   ; pbBuffer
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, &quot;uint&quot;)   ; cBuffers
NumPut(&amp;OutBuffers, OutBuffer, 8, &quot;ptr&quot;)   ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+10*A_PtrSize), &quot;ptr&quot;, &amp;hContext, &quot;ptr&quot;, &amp;OutBuffer, &quot;uint&quot;)   ; ApplyControlToken
if (scRet != SEC_E_OK)
{
   msgbox ApplyControlToken error
   exitapp
}
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, &quot;uint&quot;)   ; BufferType
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, &quot;uint&quot;)   ; cBuffers
NumPut(&amp;OutBuffers, OutBuffer, 8, &quot;ptr&quot;)   ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+6*A_PtrSize), &quot;ptr&quot;, &amp;hCreds, &quot;ptr&quot;, &amp;hContext, &quot;ptr&quot;, 0, &quot;uint&quot;, dwSSPIFlags, &quot;uint&quot;, 0, &quot;uint&quot;, SECURITY_NATIVE_DREP := 16, &quot;ptr&quot;, 0, &quot;uint&quot;, 0, &quot;ptr&quot;, &amp;hContext, &quot;ptr&quot;, &amp;OutBuffer, &quot;uint*&quot;, dwSSPIOutFlags, &quot;int64*&quot;, tsExpiry, &quot;uint&quot;)   ; InitializeSecurityContext
if (scRet &gt;= 0x80000000)
{
   msgbox InitializeSecurityContext disconnect error
   exitapp
}
OutBuffers0_cbBuffer := NumGet(OutBuffers, 0, &quot;uint&quot;)
OutBuffers0_pvBuffer := NumGet(OutBuffers, 8, &quot;ptr&quot;)
if (OutBuffers0_cbBuffer != 0) and (OutBuffers0_pvBuffer != 0)
{
   cbData := DllCall(&quot;ws2_32\send&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, OutBuffers0_pvBuffer, &quot;int&quot;, OutBuffers0_cbBuffer, &quot;int&quot;, 0)
   if (cbData &lt;= 0)
   {
      msgbox ws2_32\send close notify error
      exitapp
   }
   DllCall(NumGet(g_pSSPI+16*A_PtrSize), &quot;ptr&quot;, OutBuffers0_pvBuffer)   ; FreeContextBuffer
}
scRet := DllCall(NumGet(g_pSSPI+9*A_PtrSize), &quot;ptr&quot;, &amp;hContext, &quot;uint&quot;)   ; DeleteSecurityContext
if (scRet != SEC_E_OK)
{
   msgbox DeleteSecurityContext error
   exitapp
}
cbData := DllCall(&quot;Ws2_32\closesocket&quot;, &quot;int&quot;, socket)
if (cbData != 0)
{
   msgbox closesocket error
   exitapp
}
DllCall(&quot;ws2_32\WSACleanup&quot;)
msgbox done
ExitApp


HandshakeLoop:
VarSetCapacity(IoBuffer, IO_BUFFER_SIZE, 0)
cbIoBuffer := 0
scRet := SEC_I_CONTINUE_NEEDED
loop
{
   if (scRet = SEC_I_CONTINUE_NEEDED) or (scRet = SEC_E_INCOMPLETE_MESSAGE) or (scRet = SEC_I_INCOMPLETE_CREDENTIALS)
   {
      if (cbIoBuffer = 0) or (scRet = SEC_E_INCOMPLETE_MESSAGE)
      {
         if fDoRead
         {
            cbData := DllCall(&quot;ws2_32\recv&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;IoBuffer+cbIoBuffer, &quot;int&quot;, IO_BUFFER_SIZE-cbIoBuffer, &quot;int&quot;, 0)
            if (cbData = -1)
            {
                msgbox SOCKET_ERROR
                exitapp
            }
            else if (cbData = 0)
            {
                msgbox SEC_E_INTERNAL_ERROR
                exitapp
            }
            cbIoBuffer += cbData
         }
         else
            fDoRead := 1
      }
      VarSetCapacity(InBuffers, (8+A_PtrSize)*2, 0)
      NumPut(cbIoBuffer, InBuffers, 0, &quot;uint&quot;)   ; cbBuffer
      NumPut(SECBUFFER_TOKEN, InBuffers, 4, &quot;uint&quot;)   ; BufferType
      NumPut(&amp;IoBuffer, InBuffers, 8, &quot;ptr&quot;)   ; pbBuffer
      VarSetCapacity(InBuffer, 8+A_PtrSize, 0)
      NumPut(2, InBuffer, 4, &quot;uint&quot;)   ; cBuffers
      NumPut(&amp;InBuffers, InBuffer, 8, &quot;ptr&quot;)   ; pBuffers
      VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
      NumPut(SECBUFFER_TOKEN, OutBuffers, 4, &quot;uint&quot;)   ; BufferType
      VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
      NumPut(1, OutBuffer, 4, &quot;uint&quot;)   ; cBuffers
      NumPut(&amp;OutBuffers, OutBuffer, 8, &quot;ptr&quot;)   ; pBuffers
      scRet := DllCall(NumGet(g_pSSPI+6*A_PtrSize), &quot;ptr&quot;, &amp;hCreds, &quot;ptr&quot;, &amp;hContext, &quot;ptr&quot;, 0, &quot;uint&quot;, dwSSPIFlags, &quot;uint&quot;, 0, &quot;uint&quot;, SECURITY_NATIVE_DREP := 16, &quot;ptr&quot;, &amp;InBuffer, &quot;uint&quot;, 0, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;OutBuffer, &quot;uint*&quot;, dwSSPIOutFlags, &quot;int64*&quot;, tsExpiry, &quot;uint&quot;)   ; InitializeSecurityContext
      if (scRet = SEC_E_OK) or (scRet = SEC_I_CONTINUE_NEEDED) or ((scRet &gt;= 0x80000000) and (dwSSPIOutFlags &amp; ISC_RET_EXTENDED_ERROR))
      {
         OutBuffers0_cbBuffer := NumGet(OutBuffers, 0, &quot;uint&quot;)
         OutBuffers0_pvBuffer := NumGet(OutBuffers, 8, &quot;ptr&quot;)
         if (OutBuffers0_cbBuffer != 0) and (OutBuffers0_pvBuffer != 0)
         {
            cbData := DllCall(&quot;ws2_32\send&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, OutBuffers0_pvBuffer, &quot;int&quot;, OutBuffers0_cbBuffer, &quot;int&quot;, 0)
            if (cbData &lt;= 0)
            {
               msgbox ws2_32\send loop error
               exitapp
            }
            DllCall(NumGet(g_pSSPI+16*A_PtrSize), &quot;ptr&quot;, OutBuffers0_pvBuffer)   ; FreeContextBuffer
         }
      }
      if (scRet = SEC_E_INCOMPLETE_MESSAGE)
         Continue
      if (scRet = SEC_E_OK)
         break
      if (scRet &gt;= 0x80000000) and (scRet != SEC_I_CONTINUE_NEEDED)
      {
         msgbox InitializeSecurityContext loop error
         exitapp
      }
      if (scRet = SEC_I_INCOMPLETE_CREDENTIALS)
      {
         msgbox SEC_I_INCOMPLETE_CREDENTIALS error
         exitapp
      }
      InBuffers1_BufferType := NumGet(InBuffers, 8+A_PtrSize+4, &quot;uint&quot;)
      if (InBuffers1_BufferType = SECBUFFER_EXTRA)
      {
         InBuffers1_cbBuffer := NumGet(InBuffers, 8+A_PtrSize, &quot;uint&quot;)
         DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;IoBuffer, &quot;ptr&quot;, &amp;IoBuffer + cbIoBuffer - InBuffers1_cbBuffer, &quot;ptr&quot;, InBuffers1_cbBuffer)
         cbIoBuffer := InBuffers1_cbBuffer
      }
      else
         cbIoBuffer := 0
   }
}
return

EncryptSend:
pbMessage := &amp;pbIoBuffer+Sizes_cbHeader
cbMessage := StrLen(sendData)
StrPut(sendData, pbMessage, cbMessage, &quot;UTF-8&quot;)
VarSetCapacity(Buffers, (8+A_PtrSize)*4, 0)
NumPut(Sizes_cbHeader, Buffers, (8+A_PtrSize)*0, &quot;uint&quot;)   ; cbBuffer
NumPut(SECBUFFER_STREAM_HEADER, Buffers, (8+A_PtrSize)*0 + 4, &quot;uint&quot;)   ; BufferType
NumPut(&amp;pbIoBuffer, Buffers, (8+A_PtrSize)*0 + 8, &quot;ptr&quot;)   ; pbBuffer
NumPut(cbMessage, Buffers, (8+A_PtrSize)*1, &quot;uint&quot;)   ; cbBuffer
NumPut(SECBUFFER_DATA, Buffers, (8+A_PtrSize)*1 + 4, &quot;uint&quot;)   ; BufferType
NumPut(pbMessage, Buffers, (8+A_PtrSize)*1 + 8, &quot;ptr&quot;)   ; pbBuffer
NumPut(Sizes_cbTrailer, Buffers, (8+A_PtrSize)*2, &quot;uint&quot;)   ; cbBuffer
NumPut(SECBUFFER_STREAM_TRAILER, Buffers, (8+A_PtrSize)*2 + 4, &quot;uint&quot;)   ; BufferType
NumPut(pbMessage + cbMessage, Buffers, (8+A_PtrSize)*2 + 8, &quot;ptr&quot;)   ; pbBuffer
VarSetCapacity(Message, 8+A_PtrSize, 0)
NumPut(4, Message, 4, &quot;uint&quot;)   ; cBuffers
NumPut(&amp;Buffers, Message, 8, &quot;ptr&quot;)   ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+25*A_PtrSize), &quot;ptr&quot;, &amp;hContext, &quot;uint&quot;, 0, &quot;ptr&quot;, &amp;Message, &quot;uint&quot;)   ; EncryptMessage
if (scRet != SEC_E_OK)
{
   msgbox EncryptMessage error
   exitapp
}
cbData := DllCall(&quot;ws2_32\send&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;pbIoBuffer, &quot;int&quot;, Sizes_cbHeader + cbMessage + Sizes_cbTrailer, &quot;int&quot;, 0)
if (cbData &lt;= 0)
{
   msgbox ws2_32\send EncryptMessage error
   exitapp
}

ReadDecrypt:
DecryptedData := &quot;&quot;
cbIoBuffer := scRet := 0
loop
{
   if (cbIoBuffer = 0) or (scRet = SEC_E_INCOMPLETE_MESSAGE)
   {
      cbData := DllCall(&quot;ws2_32\recv&quot;, &quot;int&quot;, socket, &quot;ptr&quot;, &amp;pbIoBuffer+cbIoBuffer, &quot;int&quot;, cbIoBufferLength-cbIoBuffer, &quot;int&quot;, 0)
      if (cbData = -1)
      {
          msgbox SOCKET_ERROR
          exitapp
      }
      else if (cbData = 0)
      {
         if cbIoBuffer
         {
            msgbox SEC_E_INTERNAL_ERROR
            exitapp
         }
         else
            break
      }
      else
         cbIoBuffer += cbData
   }
   VarSetCapacity(Buffers, (8+A_PtrSize)*4, 0)
   NumPut(cbIoBuffer, Buffers, 0, &quot;uint&quot;)   ; cbBuffer
   NumPut(SECBUFFER_DATA, Buffers, 4, &quot;uint&quot;)   ; BufferType
   NumPut(&amp;pbIoBuffer, Buffers, 8, &quot;ptr&quot;)   ; pbBuffer
   VarSetCapacity(Message, 8+A_PtrSize, 0)
   NumPut(4, Message, 4, &quot;uint&quot;)   ; cBuffers
   NumPut(&amp;Buffers, Message, 8, &quot;ptr&quot;)   ; pBuffers
   scRet := DllCall(NumGet(g_pSSPI+26*A_PtrSize), &quot;ptr&quot;, &amp;hContext, &quot;ptr&quot;, &amp;Message, &quot;uint&quot;, 0, &quot;uint*&quot;, 0, &quot;uint&quot;)   ; DecryptMessage
   if (scRet = SEC_I_CONTEXT_EXPIRED)
      break
   if (scRet != SEC_E_OK) and (scRet != SEC_I_RENEGOTIATE) and (scRet != SEC_I_CONTEXT_EXPIRED)
   {
      msgbox DecryptMessage error
      exitapp
   }
   pDataBuffer := pExtraBuffer := &quot;&quot;
   loop 4
   {
      Buffers_BufferType := NumGet(Buffers, (A_Index-1)*(8+A_PtrSize) + 4, &quot;uint&quot;)
      if (pDataBuffer = &quot;&quot;) and (Buffers_BufferType = SECBUFFER_DATA)
         pDataBuffer  := &amp;Buffers + (A_Index-1)*(8+A_PtrSize)
      if (pExtraBuffer = &quot;&quot;) and (Buffers_BufferType = SECBUFFER_EXTRA)
         pExtraBuffer  := &amp;Buffers + (A_Index-1)*(8+A_PtrSize)
   }
   if pDataBuffer
   {
      pDataBuffer_cbBuffer := NumGet(pDataBuffer+0, 0, &quot;uint&quot;)
      pDataBuffer_pvBuffer := NumGet(pDataBuffer+0, 8, &quot;ptr&quot;)
      DecryptedData := strget(pDataBuffer_pvBuffer, pDataBuffer_cbBuffer, &quot;utf-8&quot;)
      if (Substr(DecryptedData, -1) = &quot;`r`n&quot;)
         break
   }
   if pExtraBuffer
   {
      pExtraBuffer_cbBuffer := NumGet(pExtraBuffer+0, 0, &quot;uint&quot;)
      pExtraBuffer_pvBuffer := NumGet(pExtraBuffer+0, 8, &quot;ptr&quot;)
      DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;pbIoBuffer, &quot;ptr&quot;, pExtraBuffer_pvBuffer, &quot;ptr&quot;, pExtraBuffer_cbBuffer)
      cbIoBuffer := pExtraBuffer_cbBuffer
   }
   else
      cbIoBuffer := 0
   if(scRet = SEC_I_RENEGOTIATE)
   {
      cbIoBufferPrev := cbIoBuffer
      fDoRead := 0
      GoSub HandshakeLoop
      InBuffers1_BufferType := NumGet(InBuffers, 8+A_PtrSize+4, &quot;uint&quot;)
      if (InBuffers1_BufferType = SECBUFFER_EXTRA)
      {
         InBuffers1_cbBuffer := NumGet(InBuffers, 8+A_PtrSize, &quot;uint&quot;)
         DllCall(&quot;RtlMoveMemory&quot;, &quot;ptr&quot;, &amp;pbIoBuffer, &quot;ptr&quot;, &amp;IoBuffer + cbIoBuffer - InBuffers1_cbBuffer, &quot;ptr&quot;, InBuffers1_cbBuffer)
         cbIoBuffer := InBuffers1_cbBuffer
      }
      else
         cbIoBuffer := cbIoBufferPrev
   }
}
return

base64(login, password)
{
   VarSetCapacity(bin, StrPut(login, &quot;UTF-8&quot;) + StrPut(password, &quot;UTF-8&quot;))
   size := StrPut(login, &amp;bin+1, &quot;UTF-8&quot;)
   size += StrPut(password, &amp;bin+1+size, &quot;UTF-8&quot;)
   DllCall(&quot;crypt32\CryptBinaryToString&quot;, &quot;ptr&quot;, &amp;bin, &quot;uint&quot;, size, &quot;uint&quot;, (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), &quot;ptr&quot;, 0, &quot;uint*&quot;, chars)
   VarSetCapacity(outData, chars &lt;&lt; !!A_IsUnicode, 0)
   DllCall(&quot;crypt32\CryptBinaryToString&quot;, &quot;ptr&quot;, &amp;bin, &quot;uint&quot;, size, &quot;uint&quot;, (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), &quot;str&quot;, outData, &quot;uint*&quot;, chars)
   return outData
}</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=16339">Тема для обсуждения</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Sun, 12 Mar 2023 01:38:50 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=157087#p157087</guid>
		</item>
	</channel>
</rss>
