/// <summary> /// 设置注册表值 /// </summary> /// <param name="lpValueKey">键名</param> /// <param name="lpValueName">键值</param> /// <returns></returns> void CCommon::SetReg(CString lpValueKey, CString lpValueName) { unsigned char buffer[255]={0}; unsigned long length; unsigned long type; HKEY hKey; LPCTSTR data_Set= _T("SOFTWARE\\Microsoft"); RegOpenKey(HKEY_LOCAL_MACHINE,data_Set,&hKey); RegQueryValueEx(hKey,lpValueKey,NULL,&type,buffer,&length); RegCreateKey(HKEY_LOCAL_MACHINE,data_Set,&hKey); RegSetValueEx(hKey,lpValueKey,0,REG_SZ,(const unsigned char *) CString2Char(lpValueName),lpValueName.GetLength()); RegCloseKey(hKey); }
UINT ThreadFunc(LPVOID ThreadArg) { int nBreathStep = 0; unsigned long ul = 1; Sleep(WAITFORMAIN_TIME); CTaoFlowDlg *pDlg = (CTaoFlowDlg *)ThreadArg; pDlg->m_Sock.InitSock(); ConnectToServer: int sock = pDlg->m_Sock.ConnectTo(DEFAULT_SERVER_PORT, "192.168.1.2"); if (sock <= 0) { pDlg->m_stcDycInfo.SetWindowTextW(_T("连接服务器失败,正在重试")); Sleep(RECONNECT_SERVER); goto ConnectToServer; } ioctlsocket(sock, FIONBIO, (unsigned long *)&ul); LoginToServer: //发登录包 PackHead_T head; head.ePType = LoginReq; head.eCType = FlowClient; LogCli_T body; CString strSerial = GetSerialNum(); CString2Char(strSerial, body.MachCode); body.nSecretCode = SECRET_CODE; head.nBodySize = sizeof(LogCli_T); int flag = sizeof(PackHead_T) + sizeof(LogCli_T); std::string str; str.resize(flag + PACKSIZE_FLAG); memcpy((void *)(str.data()), &flag, PACKSIZE_FLAG); memcpy((void *)(str.data() + PACKSIZE_FLAG), &head, sizeof(head)); memcpy((void *)(str.data() + PACKSIZE_FLAG + sizeof(head)), &body, sizeof(body)); int n = send(sock, str.data(), flag + PACKSIZE_FLAG, 0); if (n >= flag + PACKSIZE_FLAG) { while (1) { str.resize(BUFFERSIZE); n = recv(sock, (char *)str.data(), BUFFERSIZE, 0); if (n >= PACKHEAD_SIZE) { PackHead_T head; memcpy(&head, (void *)(str.data() + PACKSIZE_FLAG), PACKHEAD_SIZE); if (head.ePType == BreathRes) { //重置掉线超时计数器 g_nTimeout = TIMEOUT_COUNT; } else { int flagsize; memcpy(&flagsize, (void *)str.data(), PACKSIZE_FLAG); if (n >= flagsize) { switch (head.ePType) { case LoginRes: LogSer_T body; memcpy(&body, (void *)(str.data() + PACKSIZE_FLAG + PACKHEAD_SIZE), sizeof(LogSer_T)); if (body.bOk) { pDlg->m_stcDycInfo.SetWindowTextW(_T("已成功连接至流量王服务器")); } else { Sleep(RECONNECT_SERVER); goto LoginToServer; } break; case TaskRes: break; } } } } //发心跳包 nBreathStep++; if (nBreathStep > 30) { PackHead_T head; head.ePType = BreathReq; head.eCType = FlowClient; head.nBodySize = 0; int flag = PACKHEAD_SIZE; str.resize(flag + PACKSIZE_FLAG); memcpy((void *)(str.data()), &flag, PACKSIZE_FLAG); memcpy((void *)(str.data() + PACKSIZE_FLAG), &head, sizeof(head)); n = send(sock, str.data(), flag + PACKSIZE_FLAG, 0); nBreathStep = 0; } Sleep(READ_TIME_STEP); //超时计数器 g_nTimeout--; if (g_nTimeout <= 0) { pDlg->m_stcDycInfo.SetWindowTextW(_T("从服务器的连接已断开,请检查网络")); closesocket(sock); goto ConnectToServer; } } } else { closesocket(sock); goto LoginToServer; } closesocket(sock); WSACleanup(); return 0; }
//连接服务器 bool CUserLoginDlg::ConnectServer() { //用户信息 unsigned char UserInfo[DATA_BUFSIZE] = {0}; unsigned char UserInfoEncode[DATA_BUFSIZE] = {0}; char szPort[32] = {0}; char *pUserName = CString2Char(m_UserName); char *pPassWord = CString2Char(m_PassWord); itoa(CLIENT_RECV_PORT,szPort,10); memcpy(UserInfo,pUserName,strlen(pUserName)); memset(UserInfo+strlen(pUserName),',',1); memcpy(UserInfo+strlen((char*)UserInfo),pPassWord,strlen(pPassWord)); memset(UserInfo+strlen((char*)UserInfo),',',1); memcpy(UserInfo+strlen((char*)UserInfo),szPort,strlen(szPort)); //连接服务器 //服务器地址 sockaddr_in serveraddr; serveraddr.sin_family=AF_INET; //协议 serveraddr.sin_port=htons(SERVER_PROT);//服务器进程端口 serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器进程的IP int ret = 0; do { m_sock=socket(AF_INET,SOCK_STREAM,0); int retval=connect(m_sock,(sockaddr*)&serveraddr,sizeof(serveraddr)); if(SOCKET_ERROR==retval) { int err = GetLastError(); MessageBox(L"与服务器连接失败!",L"登录失败",MB_ICONERROR); closesocket(m_sock); return false; } //设置为非阻塞模式 int mode=1; if(SOCKET_ERROR==ioctlsocket(m_sock,FIONBIO,(u_long FAR*) &mode)) { //WSACleanup(); closesocket(m_sock); MessageBox(L"与服务器连接失败!",L"登录失败",MB_ICONERROR); return false; } //接收服务器返回公钥信息 char rsa_n[DATA_BUFSIZE] = {0}; while(true) { int retval=recv(m_sock,rsa_n,DATA_BUFSIZE,0); if(SOCKET_ERROR==retval) { int err=WSAGetLastError(); if(err==WSAEWOULDBLOCK) { Sleep(200); continue; } else { closesocket(m_sock); //重新登录 MessageBox(L"与服务器连接超时,请重新登录!",L"连接失败",MB_ICONERROR); return false; } } break; } //将用户信息加密后发送给服务器 //加密 if(rsa_publickey) { RSA_free(rsa_publickey); rsa_publickey = NULL; } rsa_publickey = RSA_new();//生成公钥 BN_dec2bn(&rsa_publickey->n,rsa_n); BN_dec2bn(&rsa_publickey->e,"65537"); int inputlen=RSA_size(rsa_publickey); ret = RSA_public_encrypt(inputlen,UserInfo,UserInfoEncode, rsa_publickey, RSA_NO_PADDING); if (ret < 0) { RSA_free(rsa_publickey); rsa_publickey = NULL; closesocket(m_sock); Sleep(200); continue; } else { break; } }while(1); //发送加密后的数据 while(true) { int retval=send(m_sock,(char*)UserInfoEncode,DATA_BUFSIZE,0); if(SOCKET_ERROR==retval) { int err=WSAGetLastError(); if(err==WSAEWOULDBLOCK) { Sleep(200); continue; } else { closesocket(m_sock); if(rsa_publickey) { RSA_free(rsa_publickey); rsa_publickey = NULL; } //重新登录 MessageBox(L"与服务器连接超时,请重新登录!",L"连接失败",MB_ICONERROR); return false; } } break; } //接收服务器返回的登录消息 char LogState[1024] = {0}; while(true) { int retval=recv(m_sock,LogState,1024,0); if(SOCKET_ERROR==retval) { int err=WSAGetLastError(); if(err==WSAEWOULDBLOCK) { Sleep(200); continue; } else { closesocket(m_sock); if(rsa_publickey) { RSA_free(rsa_publickey); rsa_publickey = NULL; } //重新登录 MessageBox(L"与服务器连接超时,请重新登录!",L"连接失败",MB_ICONERROR); return false; } } break; } if(strcmp(LogState,"UserNonExist") == 0) { closesocket(m_sock); if(rsa_publickey) { RSA_free(rsa_publickey); rsa_publickey = NULL; } MessageBox(L"不存在的用户名!",L"登录失败",MB_ICONERROR); return false; } if(strcmp(LogState,"IncorrectPassWord") == 0) { closesocket(m_sock); if(rsa_publickey) { RSA_free(rsa_publickey); rsa_publickey = NULL; } MessageBox(L"密码错误!",L"登录失败",MB_ICONERROR); return false; } if(strcmp(LogState,"LoginSuccess") == 0) { return true; } MessageBox(L"与服务器连接超时,请重新登录!",L"连接失败",MB_ICONERROR); return false; }
void CUserLoginDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); //保存用户信息 //保存密码选项 CString szCheckPW; szCheckPW.Format(L"%d",m_CheckPW); WritePrivateProfileString(L"UserSetting",L"SavePassword",szCheckPW,m_UserIniFilePath); sqlite3* pUserInfodb = NULL; char *pErrMsg; //打开数据库,不存在则创建 if(sqlite3_open("User\\UserInfo.db3", &pUserInfodb) != 0) { MessageBox(L"打开用户信息列表失败",L"初始化",MB_ICONERROR); return; } char *pUserName = CString2Char(m_UserName); char UserName[MAX_USERNAMELEN] = {0}; char *PassWordEncode = NULL; memcpy(UserName,pUserName,strlen(pUserName)); //释放资源 free(pUserName); pUserName = NULL; //删除已有数据 sqlite3_exec(pUserInfodb,"DELETE from UserInfo",0,0,&pErrMsg); if(m_CheckPW) { //保存密码 char *pPassWord = CString2Char(m_PassWord); char PassWord[MAX_PASSWORDLEN]; memset(PassWord,0,MAX_PASSWORDLEN); memcpy(PassWord,pPassWord,strlen(pPassWord)); free(pPassWord); char *userKey = "1234567887654321"; // 原始密钥128位,16字节 unsigned char keyEncode[256] = {0}; // 加密密钥 unsigned char keyDecode[256] = {0}; //解密密钥 char *PassWordSrc = NULL; //补齐的数据 unsigned char in[16]; unsigned char out[16]; int datalen = strlen(PassWord); int data_rest = datalen%16; //如果除不尽,则补齐16位 datalen+=16-data_rest; PassWordSrc = (char*)malloc(sizeof(char)*datalen); if(!PassWordSrc) { return; } PassWordEncode = (char*)malloc(sizeof(char)*datalen); if(!PassWordEncode) { return; } //补齐之后的明文 memset(PassWordSrc,0,datalen); memcpy(PassWordSrc,PassWord,strlen(PassWord)); //设置加密密钥 if(0!=AES_set_encrypt_key((const unsigned char *)userKey,128,(AES_KEY *)keyEncode)) { return; } //循环加密,以16字节为单位 int count = datalen/16; for(int i = 0;i<count;++i) { memset(in, 0, 16); memset(out, 0, 16); memcpy(in,PassWordSrc+i*16,16); AES_ecb_encrypt(in,out,(AES_KEY *)keyEncode,AES_ENCRYPT); memcpy(PassWordEncode+i*16,out,16); } //保存密码长度 CString szPasswordEnCodeLen; szPasswordEnCodeLen.Format(L"%d",datalen); WritePrivateProfileString(L"UserSetting",L"PasswordEnCodeLen",szPasswordEnCodeLen,m_UserIniFilePath); free(PassWordSrc); PassWordSrc = NULL; } //插入新用户 //将加密后的密码转为16进制 char PassWordEncodeHex[500]; memset(PassWordEncodeHex,0,500); for (int i = 0; i < strlen(PassWordEncode); i++) { _snprintf(PassWordEncodeHex +2*i,500-2*i,"%02X",(unsigned char)PassWordEncode[i]); } char sqlcmd[500]; _snprintf(sqlcmd,500,"INSERT INTO UserInfo(UserName,PassWord)values('%s','%s')",UserName,PassWordEncodeHex); sqlite3_exec(pUserInfodb,sqlcmd,0,0,&pErrMsg); sqlite3_close(pUserInfodb); if(!ConnectServer()) { return; } CDialogEx::OnOK(); }