SEC_WINNT_AUTH_IDENTITY 创建 (SSPI)
SEC_WINNT_AUTH_IDENTITY creation (SSPI)
我正在尝试创建一个 SEC_WINNT_AUTH_IDENTITY 以用于调用 AcquireCredentialsHandle 以获得凭据这个身份。但是我很难创建身份验证日期。
这是用于创建结构的代码:
#define SECURITY_WIN32
#include <Windows.h>
#include <sspi.h>
int main(int argc, char* argv[]) {
SEC_WINNT_AUTH_IDENTITY AuthId;
char* login = "login";
char* domain = "mydomain.com";
char* password = "pass";
AuthId.User = login;
AuthId.UserLength = strlen(login);
AuthId.Domain = domain;
AuthId.DomainLength = strlen(domain);
AuthId.Password = password;
AuthId.PasswordLength = strlen(password);
AuthId.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
//Here the call to AcquireCredentialHandle and the end of the program
}
问题是该结构需要 unsigned short __RPC_FAR *User
,但我找不到关于此的任何信息以及我应该如何将字符串传递给它。我在网上找到的例子都是直接使用字符串。
在这种情况下,ODBC 的一些经验帮助了我。但是,它不适用于 Unicode 密码,我现在不需要它。不过要是有人指点一下就好了
好吧,这是我的解决方案。我创建了助手 class:
Header:
class StringParam
{
public:
StringParam();
StringParam(const std::wstring& val);
StringParam(const std::string& val);
virtual ~StringParam();
unsigned short* GetBuffer() const;
unsigned long GetBufferLength() const;
unsigned long GetLength() const;
private:
unsigned short* buffer;
unsigned long bufferLength;
};
实施:
StringParam::StringParam():
buffer(NULL),
bufferLength(0)
{
}
StringParam::StringParam(const std::wstring& val):
StringParam()
{
size_t len = val.size(); // .length() is the same
bufferLength = sizeof(unsigned short) * (len + 1);
unsigned short* buf = new unsigned short[len + 1];
memset(buf, 0, bufferLength);
int i = 0;
for (wchar_t c: val)
buf[i++] = (unsigned short)c;
buffer = reinterpret_cast<unsigned short*>(buf);
}
StringParam::StringParam(const std::string& val):
StringParam()
{
size_t len = val.size(); // .length() is the same
bufferLength = sizeof(unsigned short) * (len + 1);
unsigned short* buf = new unsigned short[len + 1];
memset(buf, 0, bufferLength);
int i = 0;
for (char c: val)
buf[i++] = (unsigned short)c;
buffer = reinterpret_cast<unsigned short*>(buf);
}
StringParam::~StringParam()
{
if (buffer)
{
delete[] buffer;
buffer = NULL;
bufferLength = 0;
}
}
unsigned short* StringParam::GetBuffer() const
{
return buffer;
}
unsigned long StringParam::GetBufferLength() const
{
return bufferLength;
}
unsigned long StringParam::GetLength() const
{
return bufferLength / sizeof(unsigned short);
}
用法:
SECURITY_STATUS res;
// Aquire credentials
CredHandle credentials;
TimeStamp credentialsExpiryTime;
SEC_WINNT_AUTH_IDENTITY userIdentity;
StringParam prmDomain("domain.com");
StringParam prmUser("username");
StringParam prmPassword("password#1");
// wstring version will also work:
//StringParam prmDomain(L"domain.com");
//StringParam prmUser(L"username");
//StringParam prmPassword(L"password#1");
userIdentity.Domain = prmDomain.GetBuffer();
userIdentity.DomainLength = prmDomain.GetLength();
userIdentity.User = prmUser.GetBuffer();
userIdentity.UserLength = prmUser.GetLength();
userIdentity.Password = prmPassword.GetBuffer();
userIdentity.PasswordLength = prmPassword.GetLength();
userIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
res = AcquireCredentialsHandle(NULL, L"Kerberos", SECPKG_CRED_INBOUND, NULL, &userIdentity, NULL, NULL, &credentials, &credentialsExpiryTime);
对我来说效果很好。诀窍是 wchar_t 是 4 个字节长。但是 SSPI 使用 UTF-16。在 ODBC 中,从 wstring 转换的 Unicode 字符有效,但这里有所不同。
我正在尝试创建一个 SEC_WINNT_AUTH_IDENTITY 以用于调用 AcquireCredentialsHandle 以获得凭据这个身份。但是我很难创建身份验证日期。
这是用于创建结构的代码:
#define SECURITY_WIN32
#include <Windows.h>
#include <sspi.h>
int main(int argc, char* argv[]) {
SEC_WINNT_AUTH_IDENTITY AuthId;
char* login = "login";
char* domain = "mydomain.com";
char* password = "pass";
AuthId.User = login;
AuthId.UserLength = strlen(login);
AuthId.Domain = domain;
AuthId.DomainLength = strlen(domain);
AuthId.Password = password;
AuthId.PasswordLength = strlen(password);
AuthId.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
//Here the call to AcquireCredentialHandle and the end of the program
}
问题是该结构需要 unsigned short __RPC_FAR *User
,但我找不到关于此的任何信息以及我应该如何将字符串传递给它。我在网上找到的例子都是直接使用字符串。
在这种情况下,ODBC 的一些经验帮助了我。但是,它不适用于 Unicode 密码,我现在不需要它。不过要是有人指点一下就好了
好吧,这是我的解决方案。我创建了助手 class:
Header:
class StringParam
{
public:
StringParam();
StringParam(const std::wstring& val);
StringParam(const std::string& val);
virtual ~StringParam();
unsigned short* GetBuffer() const;
unsigned long GetBufferLength() const;
unsigned long GetLength() const;
private:
unsigned short* buffer;
unsigned long bufferLength;
};
实施:
StringParam::StringParam():
buffer(NULL),
bufferLength(0)
{
}
StringParam::StringParam(const std::wstring& val):
StringParam()
{
size_t len = val.size(); // .length() is the same
bufferLength = sizeof(unsigned short) * (len + 1);
unsigned short* buf = new unsigned short[len + 1];
memset(buf, 0, bufferLength);
int i = 0;
for (wchar_t c: val)
buf[i++] = (unsigned short)c;
buffer = reinterpret_cast<unsigned short*>(buf);
}
StringParam::StringParam(const std::string& val):
StringParam()
{
size_t len = val.size(); // .length() is the same
bufferLength = sizeof(unsigned short) * (len + 1);
unsigned short* buf = new unsigned short[len + 1];
memset(buf, 0, bufferLength);
int i = 0;
for (char c: val)
buf[i++] = (unsigned short)c;
buffer = reinterpret_cast<unsigned short*>(buf);
}
StringParam::~StringParam()
{
if (buffer)
{
delete[] buffer;
buffer = NULL;
bufferLength = 0;
}
}
unsigned short* StringParam::GetBuffer() const
{
return buffer;
}
unsigned long StringParam::GetBufferLength() const
{
return bufferLength;
}
unsigned long StringParam::GetLength() const
{
return bufferLength / sizeof(unsigned short);
}
用法:
SECURITY_STATUS res;
// Aquire credentials
CredHandle credentials;
TimeStamp credentialsExpiryTime;
SEC_WINNT_AUTH_IDENTITY userIdentity;
StringParam prmDomain("domain.com");
StringParam prmUser("username");
StringParam prmPassword("password#1");
// wstring version will also work:
//StringParam prmDomain(L"domain.com");
//StringParam prmUser(L"username");
//StringParam prmPassword(L"password#1");
userIdentity.Domain = prmDomain.GetBuffer();
userIdentity.DomainLength = prmDomain.GetLength();
userIdentity.User = prmUser.GetBuffer();
userIdentity.UserLength = prmUser.GetLength();
userIdentity.Password = prmPassword.GetBuffer();
userIdentity.PasswordLength = prmPassword.GetLength();
userIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
res = AcquireCredentialsHandle(NULL, L"Kerberos", SECPKG_CRED_INBOUND, NULL, &userIdentity, NULL, NULL, &credentials, &credentialsExpiryTime);
对我来说效果很好。诀窍是 wchar_t 是 4 个字节长。但是 SSPI 使用 UTF-16。在 ODBC 中,从 wstring 转换的 Unicode 字符有效,但这里有所不同。