I'm working on a way to authenticate on an smtp server with TLS
(smtp.gmail.com) using SSPI.
I found this sample code on msdn:
http://msdn.microsoft.com/en-us/library/aa380536%28VS.85%29.aspx
The function DoAuthentication was successfull but the function
QueryContextAttributes failed.
Does anyone have a working sample code to do this ?
Best regards,
Alan.
> The function DoAuthentication was successfull but the function
> QueryContextAttributes failed.
What error did it actually report? You need to be more specific.
--
Remy Lebeau (TeamB)
Hello Remy,
Thanks for your answer.
Here is the portion of code I use after receiving the response "220
2.0.0 Ready to start TLS" to the "STARTTLS\r\n" command:
------------------------------------------------------------------------------
BYTE Data[BIG_BUFF];
PCHAR pMessage;
CredHandle hCred;
struct _SecHandle hCtxt;
SECURITY_STATUS ss;
SecPkgContext_Sizes SecPkgContextSizes;
SecPkgContext_NegotiationInfo SecPkgNegInfo;
DWORD cbRead;
ULONG cbMaxSignature;
ULONG cbSecurityTrailer;
if (!DoAuthentication(Sock, &hCred, &hCtxt))
{
lstrcpyA(pszError, "Authentication failed");
goto ErrorHandler;
}
ss = QueryContextAttributes(&hCtxt, SECPKG_ATTR_NEGOTIATION_INFO,
&SecPkgNegInfo);
if (!SEC_SUCCESS(ss))
{
lstrcpyA(pszError, "QueryContextAttributes failed");
goto ErrorHandler;
}
ss = QueryContextAttributes
(&hCtxt,SECPKG_ATTR_SIZES,&SecPkgContextSizes );
if (!SEC_SUCCESS(ss))
{
lstrcpyA(pszError, "Query context failed");
goto ErrorHandler;
}
cbMaxSignature = SecPkgContextSizes.cbMaxSignature;
cbSecurityTrailer = SecPkgContextSizes.cbSecurityTrailer;
if (!ReceiveBytes(Sock, Data, BIG_BUFF, &cbRead))
{
lstrcpyA(pszError, "No response from server");
goto ErrorHandler;
}
if (0 == cbRead)
{
lstrcpyA(pszError, "Zero bytes received");
goto ErrorHandler;
}
pMessage = (PCHAR)DecryptThis(Data, &cbRead,&hCtxt,cbSecurityTrailer);
------------------------------------------------------------------------------
The function QueryContextAttributes
(&hCtxt,SECPKG_ATTR_SIZES,&SecPkgContextSizes ) returns
SEC_E_INVALID_HANDLE (The handle passed to the function is not valid).
++
> The function QueryContextAttributes returns SEC_E_INVALID_HANDLE
> (The handle passed to the function is not valid).
There is your answer then. The handle returned by your DoAuthentication()
function is not valid. Please show all of the actual code you are using,
since you are clearly not using the original code provided by Microsoft.
--
Remy Lebeau (TeamB)
The sample code on msdn does not even compile so I had to make minor
adjustments (as indicated by Mafian911 at the bottom of the page on
msdn) in the DoAuthentication function only.
Here is the DoAuthentication() function:
------------------------------------------------------------------------------
BOOL DoAuthentication(SOCKET s, CredHandle *hCred, struct _SecHandle
*hcText)
{
BOOL fDone = FALSE;
DWORD cbOut = 0;
DWORD cbIn = 0;
PBYTE pInBuf;
PBYTE pOutBuf;
if (!(pInBuf = (PBYTE) malloc(cbMaxMessage)))
{
MyHandleError("Memory allocation ");
}
if (!(pOutBuf = (PBYTE) malloc(cbMaxMessage)))
{
MyHandleError("Memory allocation ");
}
cbOut = cbMaxMessage;
if (!GenClientContext(NULL, 0, pOutBuf, &cbOut, &fDone,
TargetName,hCred,hcText))
{
return(FALSE);
}
if (!SendMsg(s, pOutBuf, cbOut))
{
MyHandleError("Send message failed ");
}
while (!fDone)
{
if (!ReceiveMsg(s, pInBuf, cbMaxMessage, &cbIn))
{
MyHandleError("Receive message failed ");
}
cbOut = cbMaxMessage;
if (!GenClientContext(pInBuf, cbIn, pOutBuf, &cbOut, &fDone,
TargetName,hCred,hcText))
{
MyHandleError("GenClientContext failed");
}
if (!SendMsg(s, pOutBuf, cbOut))
{
MyHandleError("Send message 2 failed ");
}
}
free(pInBuf);
free(pOutBuf);
return(TRUE);
}
------------------------------------------------------------------------------