BOOL CDriverProxy::DriverAuthentication(const char* szServer, int nPort, const char* szUser, const char* szPass)
{
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockClient == INVALID_SOCKET)
{
//JDLogPrint2("create socket for server error code %d ", WSAGetLastError());
return FALSE;
}
sockaddr_in serveradd;
memset(&serveradd, 0x00, sizeof(sockaddr_in));
serveradd.sin_family = AF_INET;
serveradd.sin_port = htons(nPort);
serveradd.sin_addr.S_un.S_addr = inet_addr(szServer);
if (connect(sockClient, (sockaddr *)&serveradd, sizeof(serveradd)) == SOCKET_ERROR)
{
//连接失败
printf("DriverAuthentication Connect Error!\n");
closesocket(sockClient);
return FALSE;
}
printf("DriverAuthentication begin...\n");
int index = 0;
byte Msg1[100] = {0};
//socks5协议部分(1.发送数据至服务器)
//|--------|-------------|-------------|
//| VER | NMETHOD | METHODS |
//|--------|-------------|-------------|
//| 1 | 1 | 1-255 |
//|--------|-------------|-------------|
// VER是SOCKS版本,这里应该是0x05.
// NMETHODS是METHODS部分的长度.
// METHODS是客户端支持的认证方式列表,每个方法占1字节。当前的定义是:
// 0x00 不需要认证
// 0x01 GSSAPI
// 0x02 用户名、密码认证
// 0x03 - 0x7F由IANA分配(保留)
// 0x80 - 0xFE为私人方法保留
// 0xFF 无可接受的方法
Msg1[index++] = 0x05; //Version 版本号
Msg1[index++] = 0x01; //Method 方法
Msg1[index++] = 0x02; //Username/Password 认证用户名/认证密码
//第一次发送数据
send(sockClient, (const char*)Msg1, index, 0);
char Send_Msg[100] = {0};
sprintf(Send_Msg, "VER:0x%d%d\r\n METHOD:0x%d%d\r\n Method:0x%d%d\r\n", (Msg1[0] / 16), (Msg1[0] % 16), (Msg1[1] / 16), (Msg1[1] % 16), (Msg1[2] / 16), (Msg1[2] % 16));
//MessageBoxA(NULL, (const char*)Send_Msg, "发送数据:", NULL);
printf("%s\n",Send_Msg);
byte RecvMsg1[10];
int numl = recv(sockClient, (char*)RecvMsg1, sizeof((const char*)RecvMsg1), 0);
int q00 = (RecvMsg1[0] / 16), q01 = (RecvMsg1[0] % 16);
int q10 = (RecvMsg1[1] / 16), q11 = (RecvMsg1[1] % 16);
char result[1024] = {0};
//socks5协议部分(2.服务器响应数据)
//|--------|-------------|
//| VER | METHOD |
//|--------|-------------|
//| 1 | 1 |
//|--------|-------------|
//VER是SOCKS版本,这里应该是0x05;
//METHOD是服务端选中的方法。如果返回0xFF表示没有一个认证方法被选中,客户端需要关闭连接。
sprintf(result, "Length:%d\r\n VER:0x%d%d\r\nMETHOD:0x%d%d\r\n", numl, q00, q01, q10, q11);
//MessageBoxA(NULL, result, "服务器返回结果:", NULL);
printf("%s\n", result);
if (q11 != 2)
{
closesocket(sockClient);
return FALSE;
}
//第二次发送数据
index = 0; //重置长度
byte Msg2[100] = {0};
//socks5协议部分(3.发送账号密码数据至服务器认证)
//|--------|-------------|-------------|--------|-------|
//| CVER | UserNameL | UserName | PWDL | PWD |
//|--------|-------------|-------------|--------|-------|
//| 1 | 1 | 动态 | 1 | 动态 |
//|--------|-------------|-------------|--------|-------|
// CVER是鉴定协议版本,这里应该是0x01.
// UserNameL是账户名的长度,大小为1位
// UserName是账户名本身
// PWDL是密码的长度,大小为1位
// PWDL是PWD本身
Msg2[index++] = 0x01; //Version 版本号5
Msg2[index++] = (byte)strlen(szUser); //Username length 用户名长度
for (int i = 0; i < strlen(szUser); i++) //Username 用户名
{
Msg2[index++] = (byte)szUser[i];
}
Msg2[index++] = (byte)strlen(szPass); //PWD 长度
for (int i = 0; i < strlen(szPass); i++) //PWD 密码
{
Msg2[index++] = (byte)szPass[i];
}
sprintf(Send_Msg, "CVER:0x%d%d\r\n UserNameL:0x%d%d\r\n UserName:0x%d%d 0x%d%d 0x%d%d 0x%d%d\r\n PWDL:0x%d%d\r\n PWD:0x%d%d 0x%d%d 0x%d%d 0x%d%d \r\n", (Msg2[0] / 16), (Msg2[0] % 16), (Msg2[1] / 16), (Msg2[1] % 16), (Msg2[2] / 16), (Msg2[2] % 16), (Msg2[3] / 16), (Msg2[3] % 16), (Msg2[4] / 16), (Msg2[4] % 16), (Msg2[5] / 16), (Msg2[5] % 16), (Msg2[6] / 16), (Msg2[6] % 16), (Msg2[7] / 16), (Msg2[7] % 16), (Msg2[8] / 16), (Msg2[8] % 16), (Msg2[9] / 16), (Msg2[9] % 16), (Msg2[10] / 16), (Msg2[10] % 16));
//MessageBoxA(NULL, (const char*)Send_Msg, "发送数据:", NULL);
printf("%s\n", Send_Msg);
send(sockClient, (const char*)Msg2, index, 0);
byte RecvMsg2[100] = {0};
numl = recv(sockClient, (char*)RecvMsg2, sizeof((const char*)RecvMsg2), 0);
int s00 = (RecvMsg2[0] / 16), s01 = (RecvMsg2[0] % 16);
int s10 = (RecvMsg2[1] / 16), s11 = (RecvMsg2[1] % 16);
//socks5协议部分(4.服务器响应数据)
//|--------|------------|
//| CVER | Status |
//|--------|------------|
//| 1 | 1 |
//|--------|------------|
// CVER是确认鉴定版本号
// Status为状态码:
// 1.0x00表示成功
// 1.0x01表示失败
sprintf(result, "Length:%d\r\n CVER:0x%d%d\r\nStatus:0x%d%d\r\n", numl, s00, s01, s10, s11);
//MessageBoxA(NULL, result, "服务器认证账号密码返回结果:", NULL);//第一次认证,如果为1则正确,为0则错误
printf("%s\n", result);
if (s11 != 0)
{
closesocket(sockClient);
return FALSE;
}
closesocket(sockClient);
return TRUE;
}