server := "smtp.googlemail.com"
port := 465
login := "mylogin"
password := "mypassword"
MailTo := "someone@mail.ru"
Subject := "Test from me"
EmailText := "This is a test message"
Base64 := Base64(login, password)
data =
(
EHLO Misha \r\n
AUTH PLAIN %Base64% \r\n
MAIL FROM:<%login%> \r\n
RCPT TO:<%MailTo%> \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("LoadLibrary", "str", "ws2_32.dll", "ptr")
VarSetCapacity(WSADATA, 394 + (A_PtrSize - 2) + A_PtrSize, 0)
DllCall("ws2_32\WSAStartup", "ushort", 0x0202, "ptr", &WSADATA)
socket := DllCall("ws2_32\socket", "int", PF_INET := 2, "int", SOCK_STREAM := 1, "int", 0)
sin_port := DllCall("ws2_32\htons", "ushort", port, "ushort")
VarSetCapacity(addrinfo, 16+4*A_PtrSize, 0)
NumPut(AF_INET := 2, addrinfo, 4, "int")
NumPut(SOCK_STREAM := 1, addrinfo, 8, "int")
NumPut(IPPROTO_TCP := 6, addrinfo, 12, "int")
DllCall("ws2_32\getaddrinfo", "astr", server, "ptr", 0, "ptr", &addrinfo, "ptr*", addrinfoOut)
addrinfoOut_ai_addr := NumGet(addrinfoOut+0, 16+2*A_PtrSize, "ptr")
sin_addr := NumGet(addrinfoOut_ai_addr+0, 4, "uint")
VarSetCapacity(sockaddr_in, 16, 0)
NumPut(AF_INET := 2, sockaddr_in, 0, "short") ; sin_family
NumPut(sin_port, sockaddr_in, 2, "ushort") ; sin_port
NumPut(sin_addr, sockaddr_in, 4, "uint") ; sin_addr
DllCall("ws2_32\connect", "int", socket, "ptr", &sockaddr_in, "int", 16)
DllCall("LoadLibrary","str", "Secur32.dll", "ptr")
g_pSSPI := DllCall("Secur32\InitSecurityInterface", "ptr")
VarSetCapacity(hCreds, 2*A_PtrSize, 0)
VarSetCapacity(SchannelCred, A_PtrSize*6+40, 0)
NumPut(SCHANNEL_CRED_VERSION := 4, SchannelCred, 0, "uint") ; dwVersion
NumPut(SP_PROT_TLS1_2_CLIENT := 0x800, SchannelCred, A_PtrSize*6+16, "uint") ; grbitEnabledProtocols
NumPut(SCH_CRED_NO_DEFAULT_CREDS := 0x00000010, SchannelCred, A_PtrSize*6+32, "uint") ; dwFlags
DllCall(NumGet(g_pSSPI+3*A_PtrSize), "ptr", 0, "ptr", &(UNISP_NAME := "Microsoft Unified Security Protocol Provider"), "uint", SECPKG_CRED_OUTBOUND := 0x2, "ptr", 0, "ptr", &SchannelCred, "ptr", 0, "ptr", 0, "ptr", &hCreds, "int64*", tsExpiry) ; AcquireCredentialsHandle
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, "uint") ; BufferType
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, "uint") ; cBuffers
NumPut(&OutBuffers, OutBuffer, 8, "ptr") ; pBuffers
VarSetCapacity(hContext, 2*A_PtrSize, 0)
scRet := DllCall(NumGet(g_pSSPI+6*A_PtrSize), "ptr", &hCreds, "ptr", 0, "ptr", &server, "uint", dwSSPIFlags, "uint", 0, "uint", SECURITY_NATIVE_DREP := 16, "ptr", 0, "uint", 0, "ptr", &hContext, "ptr", &OutBuffer, "uint*", dwSSPIOutFlags, "int64*", tsExpiry, "uint") ; InitializeSecurityContext
if (scRet != SEC_I_CONTINUE_NEEDED)
{
msgbox InitializeSecurityContext first time error
exitapp
}
OutBuffers0_cbBuffer := NumGet(OutBuffers, 0, "uint")
OutBuffers0_pvBuffer := NumGet(OutBuffers, 8, "ptr")
if (OutBuffers0_cbBuffer != 0) and (OutBuffers0_pvBuffer != 0)
{
cbData := DllCall("ws2_32\send", "int", socket, "ptr", OutBuffers0_pvBuffer, "int", OutBuffers0_cbBuffer, "int", 0)
if (cbData <= 0)
{
msgbox ws2_32\send first time error
exitapp
}
DllCall(NumGet(g_pSSPI+16*A_PtrSize), "ptr", OutBuffers0_pvBuffer) ; FreeContextBuffer
}
fDoRead := 1
GoSub HandshakeLoop
VarSetCapacity(Sizes, 20, 0)
scRet := DllCall(NumGet(g_pSSPI+11*A_PtrSize), "ptr", &hContext, "uint", SECPKG_ATTR_STREAM_SIZES := 4, "ptr", &Sizes, "uint") ; QueryContextAttributes
if (scRet != SEC_E_OK)
{
msgbox QueryContextAttributes error
exitapp
}
Sizes_cbHeader := NumGet(Sizes, 0, "uint")
Sizes_cbTrailer := NumGet(Sizes, 4, "uint")
Sizes_cbMaximumMessage := NumGet(Sizes, 8, "uint")
cbIoBufferLength := Sizes_cbHeader + Sizes_cbMaximumMessage + Sizes_cbTrailer
VarSetCapacity(pbIoBuffer, cbIoBufferLength, 0)
GoSub ReadDecrypt
Loop, parse, data, `n, `r
{
sendData := A_LoopField
sendData := StrReplace(sendData, "\r\n", "`r`n")
GoSub EncryptSend
}
;DisconnectFromServer
VarSetCapacity(SCHANNEL_SHUTDOWN, 4, 0)
NumPut(1, SCHANNEL_SHUTDOWN, 0, "int")
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(4, OutBuffers, 0, "uint") ; cbBuffer
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, "uint") ; BufferType
NumPut(&SCHANNEL_SHUTDOWN, OutBuffers, 8, "ptr") ; pbBuffer
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, "uint") ; cBuffers
NumPut(&OutBuffers, OutBuffer, 8, "ptr") ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+10*A_PtrSize), "ptr", &hContext, "ptr", &OutBuffer, "uint") ; ApplyControlToken
if (scRet != SEC_E_OK)
{
msgbox ApplyControlToken error
exitapp
}
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, "uint") ; BufferType
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, "uint") ; cBuffers
NumPut(&OutBuffers, OutBuffer, 8, "ptr") ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+6*A_PtrSize), "ptr", &hCreds, "ptr", &hContext, "ptr", 0, "uint", dwSSPIFlags, "uint", 0, "uint", SECURITY_NATIVE_DREP := 16, "ptr", 0, "uint", 0, "ptr", &hContext, "ptr", &OutBuffer, "uint*", dwSSPIOutFlags, "int64*", tsExpiry, "uint") ; InitializeSecurityContext
if (scRet >= 0x80000000)
{
msgbox InitializeSecurityContext disconnect error
exitapp
}
OutBuffers0_cbBuffer := NumGet(OutBuffers, 0, "uint")
OutBuffers0_pvBuffer := NumGet(OutBuffers, 8, "ptr")
if (OutBuffers0_cbBuffer != 0) and (OutBuffers0_pvBuffer != 0)
{
cbData := DllCall("ws2_32\send", "int", socket, "ptr", OutBuffers0_pvBuffer, "int", OutBuffers0_cbBuffer, "int", 0)
if (cbData <= 0)
{
msgbox ws2_32\send close notify error
exitapp
}
DllCall(NumGet(g_pSSPI+16*A_PtrSize), "ptr", OutBuffers0_pvBuffer) ; FreeContextBuffer
}
scRet := DllCall(NumGet(g_pSSPI+9*A_PtrSize), "ptr", &hContext, "uint") ; DeleteSecurityContext
if (scRet != SEC_E_OK)
{
msgbox DeleteSecurityContext error
exitapp
}
cbData := DllCall("Ws2_32\closesocket", "int", socket)
if (cbData != 0)
{
msgbox closesocket error
exitapp
}
DllCall("Ws2_32\WSACleanup")
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("ws2_32\recv", "int", socket, "ptr", &IoBuffer+cbIoBuffer, "int", IO_BUFFER_SIZE-cbIoBuffer, "int", 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, "uint") ; cbBuffer
NumPut(SECBUFFER_TOKEN, InBuffers, 4, "uint") ; BufferType
NumPut(&IoBuffer, InBuffers, 8, "ptr") ; pbBuffer
VarSetCapacity(InBuffer, 8+A_PtrSize, 0)
NumPut(2, InBuffer, 4, "uint") ; cBuffers
NumPut(&InBuffers, InBuffer, 8, "ptr") ; pBuffers
VarSetCapacity(OutBuffers, 8+A_PtrSize, 0)
NumPut(SECBUFFER_TOKEN, OutBuffers, 4, "uint") ; BufferType
VarSetCapacity(OutBuffer, 8+A_PtrSize, 0)
NumPut(1, OutBuffer, 4, "uint") ; cBuffers
NumPut(&OutBuffers, OutBuffer, 8, "ptr") ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+6*A_PtrSize), "ptr", &hCreds, "ptr", &hContext, "ptr", 0, "uint", dwSSPIFlags, "uint", 0, "uint", SECURITY_NATIVE_DREP := 16, "ptr", &InBuffer, "uint", 0, "ptr", 0, "ptr", &OutBuffer, "uint*", dwSSPIOutFlags, "int64*", tsExpiry, "uint") ; InitializeSecurityContext
if (scRet = SEC_E_OK) or (scRet = SEC_I_CONTINUE_NEEDED) or ((scRet >= 0x80000000) and (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR))
{
OutBuffers0_cbBuffer := NumGet(OutBuffers, 0, "uint")
OutBuffers0_pvBuffer := NumGet(OutBuffers, 8, "ptr")
if (OutBuffers0_cbBuffer != 0) and (OutBuffers0_pvBuffer != 0)
{
cbData := DllCall("ws2_32\send", "int", socket, "ptr", OutBuffers0_pvBuffer, "int", OutBuffers0_cbBuffer, "int", 0)
if (cbData <= 0)
{
msgbox ws2_32\send loop error
exitapp
}
DllCall(NumGet(g_pSSPI+16*A_PtrSize), "ptr", OutBuffers0_pvBuffer) ; FreeContextBuffer
}
}
if (scRet = SEC_E_INCOMPLETE_MESSAGE)
Continue
if (scRet = SEC_E_OK)
break
if (scRet >= 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, "uint")
if (InBuffers1_BufferType = SECBUFFER_EXTRA)
{
InBuffers1_cbBuffer := NumGet(InBuffers, 8+A_PtrSize, "uint")
DllCall("RtlMoveMemory", "ptr", &IoBuffer, "ptr", &IoBuffer + cbIoBuffer - InBuffers1_cbBuffer, "ptr", InBuffers1_cbBuffer)
cbIoBuffer := InBuffers1_cbBuffer
}
else
cbIoBuffer := 0
}
}
return
EncryptSend:
pbMessage := &pbIoBuffer+Sizes_cbHeader
cbMessage := StrLen(sendData)
StrPut(sendData, pbMessage, cbMessage, "UTF-8")
VarSetCapacity(Buffers, (8+A_PtrSize)*4, 0)
NumPut(Sizes_cbHeader, Buffers, (8+A_PtrSize)*0, "uint") ; cbBuffer
NumPut(SECBUFFER_STREAM_HEADER, Buffers, (8+A_PtrSize)*0 + 4, "uint") ; BufferType
NumPut(&pbIoBuffer, Buffers, (8+A_PtrSize)*0 + 8, "ptr") ; pbBuffer
NumPut(cbMessage, Buffers, (8+A_PtrSize)*1, "uint") ; cbBuffer
NumPut(SECBUFFER_DATA, Buffers, (8+A_PtrSize)*1 + 4, "uint") ; BufferType
NumPut(pbMessage, Buffers, (8+A_PtrSize)*1 + 8, "ptr") ; pbBuffer
NumPut(Sizes_cbTrailer, Buffers, (8+A_PtrSize)*2, "uint") ; cbBuffer
NumPut(SECBUFFER_STREAM_TRAILER, Buffers, (8+A_PtrSize)*2 + 4, "uint") ; BufferType
NumPut(pbMessage + cbMessage, Buffers, (8+A_PtrSize)*2 + 8, "ptr") ; pbBuffer
VarSetCapacity(Message, 8+A_PtrSize, 0)
NumPut(4, Message, 4, "uint") ; cBuffers
NumPut(&Buffers, Message, 8, "ptr") ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+25*A_PtrSize), "ptr", &hContext, "uint", 0, "ptr", &Message, "uint") ; EncryptMessage
if (scRet != SEC_E_OK)
{
msgbox EncryptMessage error
exitapp
}
cbData := DllCall("ws2_32\send", "int", socket, "ptr", &pbIoBuffer, "int", Sizes_cbHeader + cbMessage + Sizes_cbTrailer, "int", 0)
if (cbData <= 0)
{
msgbox ws2_32\send EncryptMessage error
exitapp
}
ReadDecrypt:
cbIoBuffer := scRet := 0
loop
{
if (cbIoBuffer = 0) or (scRet = SEC_E_INCOMPLETE_MESSAGE)
{
cbData := DllCall("ws2_32\recv", "int", socket, "ptr", &pbIoBuffer+cbIoBuffer, "int", cbIoBufferLength-cbIoBuffer, "int", 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, "uint") ; cbBuffer
NumPut(SECBUFFER_DATA, Buffers, 4, "uint") ; BufferType
NumPut(&pbIoBuffer, Buffers, 8, "ptr") ; pbBuffer
VarSetCapacity(Message, 8+A_PtrSize, 0)
NumPut(4, Message, 4, "uint") ; cBuffers
NumPut(&Buffers, Message, 8, "ptr") ; pBuffers
scRet := DllCall(NumGet(g_pSSPI+26*A_PtrSize), "ptr", &hContext, "ptr", &Message, "uint", 0, "uint*", 0, "uint") ; 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 := ""
loop 4
{
Buffers_BufferType := NumGet(Buffers, (A_Index-1)*(8+A_PtrSize) + 4, "uint")
if (pDataBuffer = "") and (Buffers_BufferType = SECBUFFER_DATA)
pDataBuffer := &Buffers + (A_Index-1)*(8+A_PtrSize)
if (pExtraBuffer = "") and (Buffers_BufferType = SECBUFFER_EXTRA)
pExtraBuffer := &Buffers + (A_Index-1)*(8+A_PtrSize)
}
if pDataBuffer
{
pDataBuffer_cbBuffer := NumGet(pDataBuffer+0, 0, "uint")
pDataBuffer_pvBuffer := NumGet(pDataBuffer+0, 8, "ptr")
DecryptedData := strget(pDataBuffer_pvBuffer, pDataBuffer_cbBuffer, "utf-8")
if (Substr(DecryptedData, -1) = "`r`n")
{
; msgbox % DecryptedData
break
}
}
if pExtraBuffer
{
pExtraBuffer_cbBuffer := NumGet(pExtraBuffer+0, 0, "uint")
pExtraBuffer_pvBuffer := NumGet(pExtraBuffer+0, 8, "ptr")
DllCall("RtlMoveMemory", "ptr", &pbIoBuffer, "ptr", pExtraBuffer_pvBuffer, "ptr", 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, "uint")
if (InBuffers1_BufferType = SECBUFFER_EXTRA)
{
InBuffers1_cbBuffer := NumGet(InBuffers, 8+A_PtrSize, "uint")
DllCall("RtlMoveMemory", "ptr", &pbIoBuffer, "ptr", &IoBuffer + cbIoBuffer - InBuffers1_cbBuffer, "ptr", InBuffers1_cbBuffer)
cbIoBuffer := InBuffers1_cbBuffer
}
else
cbIoBuffer := cbIoBufferPrev
}
}
return
base64(login, password)
{
VarSetCapacity(bin, StrPut(login, "UTF-8") + StrPut(password, "UTF-8"))
size := StrPut(login, &bin+1, "UTF-8")
size += StrPut(password, &bin+1+size, "UTF-8")
DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", size, "uint", (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), "ptr", 0, "uint*", chars)
VarSetCapacity(outData, chars << !!A_IsUnicode, 0)
DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", size, "uint", (CRYPT_STRING_BASE64 := 0x1)|(CRYPT_STRING_NOCRLF := 0x40000000), "str", outData, "uint*", chars)
return outData
}
Пароль должен быть специальным паролем для приложений.