string UrlGB2312Decode(string str) { string output=""; char tmp[2]; int i=0,len=str.length(); while(i<len){ if(str[i]=='%'){ tmp[0]=str[i+1]; tmp[1]=str[i+2]; output += StrToBin(tmp); i=i+3; } else if(str[i]=='+'){ output+=' '; i++; } else{ output+=str[i]; i++; } } return output; }
// Convert the string to a MAC address bool StrToMac(UCHAR *mac_address, char *str) { BUF *b; // Validate arguments if (mac_address == NULL || str == NULL) { return false; } b = StrToBin(str); if (b == NULL) { return false; } if (b->Size != 6) { FreeBuf(b); return false; } Copy(mac_address, b->Buf, 6); FreeBuf(b); return true; }
// 仮想ホストオプションの読み込み (拡張) void NiLoadVhOptionEx(VH_OPTION *o, FOLDER *root) { FOLDER *host, *nat, *dhcp; char mac_address[MAX_SIZE]; // 引数チェック if (o == NULL || root == NULL) { return; } host = CfgGetFolder(root, "VirtualHost"); nat = CfgGetFolder(root, "VirtualRouter"); dhcp = CfgGetFolder(root, "VirtualDhcpServer"); Zero(o, sizeof(VH_OPTION)); GenMacAddress(o->MacAddress); if (CfgGetStr(host, "VirtualHostMacAddress", mac_address, sizeof(mac_address))) { BUF *b = StrToBin(mac_address); if (b != NULL) { if (b->Size == 6) { Copy(o->MacAddress, b->Buf, 6); } } FreeBuf(b); } CfgGetIp(host, "VirtualHostIp", &o->Ip); CfgGetIp(host, "VirtualHostIpSubnetMask", &o->Mask); o->UseNat = CfgGetBool(nat, "NatEnabled"); o->Mtu = CfgGetInt(nat, "NatMtu"); o->NatTcpTimeout = CfgGetInt(nat, "NatTcpTimeout"); o->NatUdpTimeout = CfgGetInt(nat, "NatUdpTimeout"); o->UseDhcp = CfgGetBool(dhcp, "DhcpEnabled"); CfgGetIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart); CfgGetIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd); CfgGetIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask); o->DhcpExpireTimeSpan = CfgGetInt(dhcp, "DhcpExpireTimeSpan"); CfgGetIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress); CfgGetIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress); CfgGetStr(dhcp, "DhcpDomainName", o->DhcpDomainName, sizeof(o->DhcpDomainName)); Trim(o->DhcpDomainName); if (StrLen(o->DhcpDomainName) == 0) { //GetDomainName(o->DhcpDomainName, sizeof(o->DhcpDomainName)); } o->SaveLog = CfgGetBool(root, "SaveLog"); }
// Convert the contents of the form to the VH_OPTION void NmEditVhOptionFormToVH(HWND hWnd, VH_OPTION *t) { char tmp[MAX_SIZE]; BUF *b; // Validate arguments if (hWnd == NULL || t == NULL) { return; } Zero(t, sizeof(VH_OPTION)); GetTxtA(hWnd, E_MAC, tmp, sizeof(tmp)); b = StrToBin(tmp); if (b != NULL) { if (b->Size == 6) { Copy(t->MacAddress, b->Buf, 6); } FreeBuf(b); } UINTToIP(&t->Ip, IpGet(hWnd, E_IP)); UINTToIP(&t->Mask, IpGet(hWnd, E_MASK)); t->UseNat = IsChecked(hWnd, R_USE_NAT); t->Mtu = GetInt(hWnd, E_MTU); t->NatTcpTimeout = GetInt(hWnd, E_TCP); t->NatUdpTimeout = GetInt(hWnd, E_UDP); t->UseDhcp = IsChecked(hWnd, R_USE_DHCP); UINTToIP(&t->DhcpLeaseIPStart, IpGet(hWnd, E_DHCP_START)); UINTToIP(&t->DhcpLeaseIPEnd, IpGet(hWnd, E_DHCP_END)); UINTToIP(&t->DhcpSubnetMask, IpGet(hWnd, E_DHCP_MASK)); t->DhcpExpireTimeSpan = GetInt(hWnd, E_EXPIRES); UINTToIP(&t->DhcpGatewayAddress, IpGet(hWnd, E_GATEWAY)); UINTToIP(&t->DhcpDnsServerAddress, IpGet(hWnd, E_DNS)); UINTToIP(&t->DhcpDnsServerAddress2, IpGet(hWnd, E_DNS2)); GetTxtA(hWnd, E_DOMAIN, t->DhcpDomainName, sizeof(t->DhcpDomainName)); t->SaveLog = IsChecked(hWnd, R_SAVE_LOG); }
UINT DCGetMyIpMain(DDNS_CLIENT *c, bool ipv6, char *dst, UINT dst_size, bool use_ssl, char *replace_v6) { char *url; char url2[MAX_SIZE]; UINT ret = ERR_INTERNAL_ERROR; URL_DATA data; BUF *recv; BUF *cert_hash; // Validate arguments if (dst == NULL || c == NULL) { return ERR_INTERNAL_ERROR; } if (ipv6 == false) { url = DDNS_URL2_V4_GLOBAL; if (IsUseAlternativeHostname()) { url = DDNS_URL2_V4_ALT; } } else { url = DDNS_URL2_V6_GLOBAL; if (IsUseAlternativeHostname()) { url = DDNS_URL2_V6_ALT; } if (replace_v6) { url = replace_v6; } } Format(url2, sizeof(url2), "%s?v=%I64u", url, Rand64()); if (use_ssl) { ReplaceStr(url2, sizeof(url2), url2, "http://", "https://"); } if (ParseUrl(&data, url2, false, NULL) == false) { return ERR_INTERNAL_ERROR; } cert_hash = StrToBin(DDNS_CERT_HASH); recv = HttpRequest(&data, (ipv6 ? NULL : &c->InternetSetting), DDNS_CONNECT_TIMEOUT, DDNS_COMM_TIMEOUT, &ret, false, NULL, NULL, NULL, ((cert_hash != NULL && cert_hash->Size == SHA1_SIZE) ? cert_hash->Buf : NULL)); FreeBuf(cert_hash); if (recv != NULL) { char *str = ZeroMalloc(recv->Size + 1); Copy(str, recv->Buf, recv->Size); if (StartWith(str, "IP=") == false) { ret = ERR_PROTOCOL_ERROR; } else { StrCpy(dst, dst_size, str + 3); ret = ERR_NO_ERROR; } Free(str); FreeBuf(recv); } if (IsUseAlternativeHostname() == false) { if (ret == ERR_CONNECT_FAILED) { if (ipv6 && replace_v6 == NULL && use_ssl == false) { UINT type = DetectFletsType(); if (type & FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE && ret != ERR_NO_ERROR) { ret = DCGetMyIpMain(c, ipv6, dst, dst_size, use_ssl, DDNS_REPLACE_URL2_FOR_EAST_BFLETS); } if (type & FLETS_DETECT_TYPE_EAST_NGN_PRIVATE && ret != ERR_NO_ERROR) { ret = DCGetMyIpMain(c, ipv6, dst, dst_size, use_ssl, DDNS_REPLACE_URL2_FOR_EAST_NGN); } if (type & FLETS_DETECT_TYPE_WEST_NGN_PRIVATE && ret != ERR_NO_ERROR) { ret = DCGetMyIpMain(c, ipv6, dst, dst_size, use_ssl, DDNS_REPLACE_URL2_FOR_WEST_NGN); } } } } return ret; }
// Execution of registration UINT DCRegister(DDNS_CLIENT *c, bool ipv6, DDNS_REGISTER_PARAM *p, char *replace_v6) { char *url; char url2[MAX_SIZE]; char url3[MAX_SIZE]; PACK *req, *ret; char key_str[MAX_SIZE]; UCHAR machine_key[SHA1_SIZE]; char machine_key_str[MAX_SIZE]; char machine_name[MAX_SIZE]; BUF *cert_hash; UINT err = ERR_INTERNAL_ERROR; UCHAR key_hash[SHA1_SIZE]; char key_hash_str[MAX_SIZE]; bool use_azure = false; char current_azure_ip[MAX_SIZE]; INTERNET_SETTING t; UINT build = 0; bool use_https = false; bool use_vgs = false; // Validate arguments if (c == NULL) { return ERR_INTERNAL_ERROR; } Zero(current_azure_ip, sizeof(current_azure_ip)); GetCurrentMachineIpProcessHash(machine_key); BinToStr(machine_key_str, sizeof(machine_key_str), machine_key, sizeof(machine_key)); GetMachineHostName(machine_name, sizeof(machine_name)); StrLower(machine_name); if (ipv6 == false) { url = DDNS_URL_V4_GLOBAL; if (IsUseAlternativeHostname()) { url = DDNS_URL_V4_ALT; } } else { url = DDNS_URL_V6_GLOBAL; if (IsUseAlternativeHostname()) { url = DDNS_URL_V6_ALT; } if (replace_v6) { url = replace_v6; } } Zero(&t, sizeof(t)); if (ipv6 == false) { // Proxy Setting Copy(&t, &c->InternetSetting, sizeof(INTERNET_SETTING)); } if (ipv6 == false) { // Get the current status of the VPN Azure Client if (c->Cedar->Server != NULL) { AZURE_CLIENT *ac = c->Cedar->Server->AzureClient; if (ac != NULL) { use_azure = SiIsAzureEnabled(c->Cedar->Server); if (use_azure) { Lock(ac->Lock); { StrCpy(current_azure_ip, sizeof(current_azure_ip), ac->ConnectingAzureIp); } Unlock(ac->Lock); } } } } req = NewPack(); BinToStr(key_str, sizeof(key_str), c->Key, sizeof(c->Key)); StrUpper(key_str); PackAddStr(req, "key", key_str); // Build Number build = c->Cedar->Build; PackAddInt(req, "build", build); PackAddInt(req, "osinfo", GetOsInfo()->OsType); PackAddInt(req, "is_64bit", Is64()); #ifdef OS_WIN32 PackAddInt(req, "is_windows_64bit", MsIs64BitWindows()); #endif // OS_WIN32 PackAddBool(req, "is_softether", true); PackAddBool(req, "is_packetix", false); PackAddStr(req, "machine_key", machine_key_str); PackAddStr(req, "machine_name", machine_name); PackAddInt(req, "lasterror_ipv4", c->Err_IPv4_GetMyIp); PackAddInt(req, "lasterror_ipv6", c->Err_IPv6_GetMyIp); PackAddBool(req, "use_azure", use_azure); PackAddStr(req, "product_str", CEDAR_PRODUCT_STR); PackAddInt(req, "ddns_protocol_version", DDNS_VERSION); if (use_azure) { Debug("current_azure_ip = %s\n", current_azure_ip); PackAddStr(req, "current_azure_ip", current_azure_ip); } HashSha1(key_hash, key_str, StrLen(key_str)); BinToStr(key_hash_str, sizeof(key_hash_str), key_hash, sizeof(key_hash)); StrLower(key_hash_str); if (p != NULL) { if (IsEmptyStr(p->NewHostname) == false) { PackAddStr(req, "new_hostname", p->NewHostname); } } cert_hash = StrToBin(DDNS_CERT_HASH); Format(url2, sizeof(url2), "%s?v=%I64u", url, Rand64()); Format(url3, sizeof(url3), url2, key_hash_str[0], key_hash_str[1], key_hash_str[2], key_hash_str[3]); if (use_https == false) { ReplaceStr(url3, sizeof(url3), url3, "https://", "http://"); } ReplaceStr(url3, sizeof(url3), url3, ".servers", ".open.servers"); Debug("WpcCall: %s\n", url3); ret = WpcCallEx(url3, &t, DDNS_CONNECT_TIMEOUT, DDNS_COMM_TIMEOUT, "register", req, NULL, NULL, ((cert_hash != NULL && cert_hash->Size == SHA1_SIZE) ? cert_hash->Buf : NULL), NULL, DDNS_RPC_MAX_RECV_SIZE); Debug("WpcCall Ret: %u\n", ret); FreeBuf(cert_hash); FreePack(req); err = GetErrorFromPack(ret); ExtractAndApplyDynList(ret); // Status update Lock(c->Lock); { if (err == ERR_NO_ERROR) { char snat_t[MAX_SIZE]; char current_region[128]; // Current host name PackGetStr(ret, "current_hostname", c->CurrentHostName, sizeof(c->CurrentHostName)); PackGetStr(ret, "current_fqdn", c->CurrentFqdn, sizeof(c->CurrentFqdn)); PackGetStr(ret, "current_ipv4", c->CurrentIPv4, sizeof(c->CurrentIPv4)); PackGetStr(ret, "current_ipv6", c->CurrentIPv6, sizeof(c->CurrentIPv6)); PackGetStr(ret, "dns_suffix", c->DnsSuffix, sizeof(c->DnsSuffix)); PackGetStr(ret, "current_region", current_region, sizeof(current_region)); // SecureNAT connectivity check parameters Zero(snat_t, sizeof(snat_t)); PackGetStr(ret, "snat_t", snat_t, sizeof(snat_t)); NnSetSecureNatTargetHostname(snat_t); if (ipv6 == false) { char cert_hash[MAX_SIZE]; PackGetStr(ret, "current_azure_ip", c->CurrentAzureIp, sizeof(c->CurrentAzureIp)); c->CurrentAzureTimestamp = PackGetInt64(ret, "current_azure_timestamp"); PackGetStr(ret, "current_azure_signature", c->CurrentAzureSignature, sizeof(c->CurrentAzureSignature)); Zero(cert_hash, sizeof(cert_hash)); PackGetStr(ret, "azure_cert_hash", cert_hash, sizeof(cert_hash)); if (IsEmptyStr(cert_hash) == false) { StrCpy(c->AzureCertHash, sizeof(c->AzureCertHash), cert_hash); } } StrCpy(c->Cedar->CurrentDDnsFqdn, sizeof(c->Cedar->CurrentDDnsFqdn), c->CurrentFqdn); Debug("current_hostname=%s, current_fqdn=%s, current_ipv4=%s, current_ipv6=%s, current_azure_ip=%s, CurrentAzureTimestamp=%I64u, CurrentAzureSignature=%s, CertHash=%s\n", c->CurrentHostName, c->CurrentFqdn, c->CurrentIPv4, c->CurrentIPv6, c->CurrentAzureIp, c->CurrentAzureTimestamp, c->CurrentAzureSignature, c->AzureCertHash); if (IsEmptyStr(current_region) == false) { // Update the current region SiUpdateCurrentRegion(c->Cedar, current_region, false); } } } Unlock(c->Lock); if (IsEmptyStr(c->CurrentFqdn) == false) { SetCurrentDDnsFqdn(c->CurrentFqdn); } FreePack(ret); UniDebug(L"DCRegister Error: %s\n", _E(err)); if (err == ERR_DUPLICATE_DDNS_KEY) { // Key duplication DCGenNewKey(c->Key); c->KeyChanged = true; } if (err == ERR_DISCONNECTED) { err = ERR_DDNS_DISCONNECTED; } if (IsUseAlternativeHostname() == false) { if (err == ERR_CONNECT_FAILED) { if (ipv6 && replace_v6 == NULL) { UINT type = DetectFletsType(); if (type & FLETS_DETECT_TYPE_EAST_BFLETS_PRIVATE && err != ERR_NO_ERROR) { err = DCRegister(c, ipv6, p, DDNS_REPLACE_URL_FOR_EAST_BFLETS); } if (type & FLETS_DETECT_TYPE_EAST_NGN_PRIVATE && err != ERR_NO_ERROR) { err = DCRegister(c, ipv6, p, DDNS_REPLACE_URL_FOR_EAST_NGN); } if (type & FLETS_DETECT_TYPE_WEST_NGN_PRIVATE && err != ERR_NO_ERROR) { err = DCRegister(c, ipv6, p, DDNS_REPLACE_URL_FOR_WEST_NGN); } } } } return err; }
// Attempts Radius authentication (with specifying retry interval and multiple server) bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20) { UCHAR random[MD5_SIZE]; UCHAR id; BUF *encrypted_password = NULL; BUF *user_name = NULL; //IP ip; bool ret = false; TOKEN_LIST *token; UINT i; LIST *ip_list; IPC_MSCHAP_V2_AUTHINFO mschap; bool is_mschap; char client_ip_str[MAX_SIZE]; static UINT packet_id = 0; // Validate arguments if (server == NULL || port == 0 || (secret_size != 0 && secret == NULL) || username == NULL || password == NULL) { return false; } Zero(client_ip_str, sizeof(client_ip_str)); if (c != NULL && c->FirstSock != NULL) { IPToStr(client_ip_str, sizeof(client_ip_str), &c->FirstSock->RemoteIP); } // Parse the MS-CHAP v2 authentication data Zero(&mschap, sizeof(mschap)); is_mschap = ParseAndExtractMsChapV2InfoFromPassword(&mschap, password); // Split the server into tokens token = ParseToken(server, " ,;\t"); // Get the IP address of the server ip_list = NewListFast(NULL); for(i = 0; i < token->NumTokens; i++) { IP *tmp_ip = Malloc(sizeof(IP)); if (GetIP(tmp_ip, token->Token[i])) { Add(ip_list, tmp_ip); } else if (GetIPEx(tmp_ip, token->Token[i], true)) { Add(ip_list, tmp_ip); } else { Free(tmp_ip); } } FreeToken(token); if(LIST_NUM(ip_list) == 0) { ReleaseList(ip_list); return false; } // Random number generation Rand(random, sizeof(random)); // ID generation id = (UCHAR)(packet_id % 254 + 1); packet_id++; if (is_mschap == false) { // Encrypt the password encrypted_password = RadiusEncryptPassword(password, random, secret, secret_size); if (encrypted_password == NULL) { // Encryption failure ReleaseList(ip_list); return false; } } // Generate the user name packet user_name = RadiusCreateUserName(username); if (user_name != NULL) { // Generate a password packet BUF *user_password = (is_mschap ? NULL : RadiusCreateUserPassword(encrypted_password->Buf, encrypted_password->Size)); BUF *nas_id = RadiusCreateNasId(CEDAR_SERVER_STR); if (is_mschap || user_password != NULL) { UINT64 start; UINT64 next_send_time; UCHAR tmp[MAX_SIZE]; UINT recv_buf_size = 32768; UCHAR *recv_buf = MallocEx(recv_buf_size, true); // Generate an UDP packet BUF *p = NewBuf(); UCHAR type = 1; SOCK *sock; USHORT sz = 0; UINT pos = 0; BOOL *finish = ZeroMallocEx(sizeof(BOOL) * LIST_NUM(ip_list), true); Zero(tmp, sizeof(tmp)); WriteBuf(p, &type, 1); WriteBuf(p, &id, 1); WriteBuf(p, &sz, 2); WriteBuf(p, random, 16); WriteBuf(p, user_name->Buf, user_name->Size); if (is_mschap == false) { UINT ui; // PAP WriteBuf(p, user_password->Buf, user_password->Size); WriteBuf(p, nas_id->Buf, nas_id->Size); // Service-Type ui = Endian32(2); RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); // NAS-Port-Type ui = Endian32(5); RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); // Tunnel-Type ui = Endian32(1); RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); // Tunnel-Medium-Type ui = Endian32(1); RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); // Calling-Station-Id RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); // Tunnel-Client-Endpoint RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); } else { // MS-CHAP v2 static UINT session_id = 0; USHORT us; UINT ui; char *ms_ras_version = "MSRASV5.20"; UCHAR ms_chapv2_response[50]; // Acct-Session-Id us = Endian16(session_id % 254 + 1); session_id++; RadiusAddValue(p, 44, 0, 0, &us, sizeof(us)); // NAS-IP-Address if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false) { ui = IPToUINT(&c->FirstSock->LocalIP); RadiusAddValue(p, 4, 0, 0, &ui, sizeof(ui)); } // Service-Type ui = Endian32(2); RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); // MS-RAS-Vendor ui = Endian32(311); RadiusAddValue(p, 26, 311, 9, &ui, sizeof(ui)); // MS-RAS-Version RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version)); // NAS-Port-Type ui = Endian32(5); RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); // Tunnel-Type ui = Endian32(1); RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); // Tunnel-Medium-Type ui = Endian32(1); RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); // Calling-Station-Id RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); // Tunnel-Client-Endpoint RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); // MS-RAS-Client-Version RadiusAddValue(p, 26, 311, 35, ms_ras_version, StrLen(ms_ras_version)); // MS-RAS-Client-Name RadiusAddValue(p, 26, 311, 34, client_ip_str, StrLen(client_ip_str)); // MS-CHAP-Challenge RadiusAddValue(p, 26, 311, 11, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge)); // MS-CHAP2-Response Zero(ms_chapv2_response, sizeof(ms_chapv2_response)); Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16); Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24); RadiusAddValue(p, 26, 311, 25, ms_chapv2_response, sizeof(ms_chapv2_response)); // NAS-ID WriteBuf(p, nas_id->Buf, nas_id->Size); } SeekBuf(p, 0, 0); WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size); // Create a socket sock = NewUDPEx(0, IsIP6(LIST_DATA(ip_list, pos))); // Transmission process start start = Tick64(); if(interval < RADIUS_RETRY_INTERVAL) { interval = RADIUS_RETRY_INTERVAL; } else if(interval > RADIUS_RETRY_TIMEOUT) { interval = RADIUS_RETRY_TIMEOUT; } next_send_time = start + (UINT64)interval; while (true) { UINT server_port; UINT recv_size; //IP server_ip; SOCKSET set; UINT64 now; SEND_RETRY: //SendTo(sock, &ip, port, p->Buf, p->Size); SendTo(sock, LIST_DATA(ip_list, pos), port, p->Buf, p->Size); Debug("send to host:%u\n", pos); next_send_time = Tick64() + (UINT64)interval; RECV_RETRY: now = Tick64(); if (next_send_time <= now) { // Switch the host to refer pos++; pos = pos % LIST_NUM(ip_list); goto SEND_RETRY; } if ((start + RADIUS_RETRY_TIMEOUT) < now) { // Time-out break; } InitSockSet(&set); AddSockSet(&set, sock); Select(&set, (UINT)(next_send_time - now), NULL, NULL); recv_size = RecvFrom(sock, LIST_DATA(ip_list, pos), &server_port, recv_buf, recv_buf_size); if (recv_size == 0) { Debug("Radius recv_size 0\n"); finish[pos] = TRUE; for(i = 0; i < LIST_NUM(ip_list); i++) { if(finish[i] == FALSE) { // Switch the host to refer pos++; pos = pos % LIST_NUM(ip_list); goto SEND_RETRY; } } // Failure break; } else if (recv_size == SOCK_LATER) { // Waiting goto RECV_RETRY; } else { // Check such as the IP address if (/*Cmp(&server_ip, &ip, sizeof(IP)) != 0 || */server_port != port) { goto RECV_RETRY; } // Success if (recv_buf[0] == 2) { ret = true; if (is_mschap && mschap_v2_server_response_20 != NULL) { // Cutting corners Zurukko UCHAR signature[] = {0x1A, 0x33, 0x00, 0x00, 0x01, 0x37, 0x1A, 0x2D, 0x00, 0x53, 0x3D, }; UINT i = SearchBin(recv_buf, 0, recv_buf_size, signature, sizeof(signature)); if (i == INFINITE || ((i + sizeof(signature) + 40) > recv_buf_size)) { ret = false; } else { char tmp[MAX_SIZE]; BUF *b; Zero(tmp, sizeof(tmp)); Copy(tmp, recv_buf + i + sizeof(signature), 40); b = StrToBin(tmp); if (b != NULL && b->Size == 20) { WHERE; Copy(mschap_v2_server_response_20, b->Buf, 20); } else { WHERE; ret = false; } FreeBuf(b); } } } break; } } Free(finish); // Release the socket ReleaseSock(sock); FreeBuf(p); FreeBuf(user_password); Free(recv_buf); } FreeBuf(nas_id); FreeBuf(user_name); } // Release the ip_list for(i = 0; i < LIST_NUM(ip_list); i++) { IP *tmp_ip = LIST_DATA(ip_list, i); Free(tmp_ip); } ReleaseList(ip_list); // Release the memory FreeBuf(encrypted_password); return ret; }
// Read the virtual host option (extended) void NiLoadVhOptionEx(VH_OPTION *o, FOLDER *root) { FOLDER *host, *nat, *dhcp; char mac_address[MAX_SIZE]; // Validate arguments if (o == NULL || root == NULL) { return; } host = CfgGetFolder(root, "VirtualHost"); nat = CfgGetFolder(root, "VirtualRouter"); dhcp = CfgGetFolder(root, "VirtualDhcpServer"); Zero(o, sizeof(VH_OPTION)); GenMacAddress(o->MacAddress); if (CfgGetStr(host, "VirtualHostMacAddress", mac_address, sizeof(mac_address))) { BUF *b = StrToBin(mac_address); if (b != NULL) { if (b->Size == 6) { Copy(o->MacAddress, b->Buf, 6); } } FreeBuf(b); } CfgGetIp(host, "VirtualHostIp", &o->Ip); CfgGetIp(host, "VirtualHostIpSubnetMask", &o->Mask); o->UseNat = CfgGetBool(nat, "NatEnabled"); o->Mtu = CfgGetInt(nat, "NatMtu"); o->NatTcpTimeout = CfgGetInt(nat, "NatTcpTimeout"); o->NatUdpTimeout = CfgGetInt(nat, "NatUdpTimeout"); o->UseDhcp = CfgGetBool(dhcp, "DhcpEnabled"); CfgGetIp(dhcp, "DhcpLeaseIPStart", &o->DhcpLeaseIPStart); CfgGetIp(dhcp, "DhcpLeaseIPEnd", &o->DhcpLeaseIPEnd); CfgGetIp(dhcp, "DhcpSubnetMask", &o->DhcpSubnetMask); o->DhcpExpireTimeSpan = CfgGetInt(dhcp, "DhcpExpireTimeSpan"); CfgGetIp(dhcp, "DhcpGatewayAddress", &o->DhcpGatewayAddress); CfgGetIp(dhcp, "DhcpDnsServerAddress", &o->DhcpDnsServerAddress); CfgGetIp(dhcp, "DhcpDnsServerAddress2", &o->DhcpDnsServerAddress2); CfgGetStr(dhcp, "DhcpDomainName", o->DhcpDomainName, sizeof(o->DhcpDomainName)); CfgGetStr(dhcp, "DhcpPushRoutes", o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes)); // Test code // StrCpy(o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes), // "130.158.6.0/24/192.168.9.2 130.158.80.244/255.255.255.255/192.168.9.2"); NormalizeClasslessRouteTableStr(o->DhcpPushRoutes, sizeof(o->DhcpPushRoutes), o->DhcpPushRoutes); o->ApplyDhcpPushRoutes = true; Trim(o->DhcpDomainName); if (StrLen(o->DhcpDomainName) == 0) { //GetDomainName(o->DhcpDomainName, sizeof(o->DhcpDomainName)); } o->SaveLog = CfgGetBool(root, "SaveLog"); }
bool SmbAuthenticate(char* name, char* password, char* domainname, char* groupname, UINT timeout, UCHAR* challenge8, UCHAR* MsChapV2_ClientResponse, UCHAR* nt_pw_hash_hash) { bool auth = false; int fds[2]; FILE* out, *in; PID pid; char buffer[255]; char ntlm_timeout[32]; char* proc_parameter[6]; if (name == NULL || password == NULL || domainname == NULL || groupname == NULL) { Debug("Sam.c - SmbAuthenticate - wrong password parameter\n"); return false; } if (password[0] == '\0' && (challenge8 == NULL || MsChapV2_ClientResponse == NULL || nt_pw_hash_hash == NULL)) { Debug("Sam.c - SmbAuthenticate - wrong MsCHAPv2 parameter\n"); return false; } Zero(buffer, sizeof(buffer)); // Truncate string if unsafe char EnSafeStr(domainname, '\0'); if (strlen(domainname) > 255) { // there is no domainname longer then 255 chars! // http://tools.ietf.org/html/rfc1035 section 2.3.4 domainname[255] = '\0'; } // set timeout to 15 minutes even if timeout is disabled, to prevent ntlm_auth from hung up if (timeout <= 0 || timeout > 900) { timeout = 999; } snprintf(ntlm_timeout, sizeof(ntlm_timeout), "%is", timeout); Debug("Sam.c - timeout for ntlm_auth %s\n", ntlm_timeout); proc_parameter[0] = "timeout"; proc_parameter[1] = ntlm_timeout; proc_parameter[2] = "ntlm_auth"; proc_parameter[3] = "--helper-protocol=ntlm-server-1"; proc_parameter[4] = 0; if (strlen(groupname) > 1) { // DNS Name 255 chars + OU names are limited to 64 characters + cmdline 32 + 1 char requiremember[352]; // Truncate string if unsafe char EnSafeStr(groupname, '\0'); snprintf(requiremember, sizeof(requiremember), "--require-membership-of=%s\\%s", domainname, groupname); proc_parameter[4] = requiremember; proc_parameter[5] = 0; } pid = OpenChildProcess("timeout", proc_parameter, fds); if (pid < 0) { Debug("Sam.c - SmbCheckLogon - error fork child process (ntlm_auth)\n"); return false; } out = fdopen(fds[1], "w"); if (out == 0) { CloseChildProcess(pid, fds); Debug("Sam.c - cant open out pipe (ntlm_auth)\n"); return false; } in = fdopen(fds[0], "r"); if (in == 0) { fclose(out); CloseChildProcess(pid, fds); Debug("Sam.c - cant open in pipe (ntlm_auth)\n"); return false; } if (base64_enc_len(strlen(name)) < sizeof(buffer)-1 && base64_enc_len(strlen(password)) < sizeof(buffer)-1 && base64_enc_len(strlen(domainname)) < sizeof(buffer)-1) { char answer[300]; unsigned int end = B64_Encode(buffer, name, strlen(name)); buffer[end] = '\0'; fputs("Username:: ", out); fputs(buffer, out); fputs("\n", out); Debug("Username: %s\n", buffer); buffer[0] = 0; end = B64_Encode(buffer, domainname, strlen(domainname)); buffer[end] = '\0'; fputs("NT-Domain:: ", out); fputs(buffer, out); fputs("\n", out); Debug("NT-Domain: %s\n", buffer); buffer[0] = 0; if (password[0] != '\0') { Debug("Password authentication\n"); end = B64_Encode(buffer, password, strlen(password)); buffer[end] = '\0'; fputs("Password:: ", out); fputs(buffer, out); fputs("\n", out); Debug("Password: %s\n", buffer); buffer[0] = 0; } else { char* mschapv2_client_response; char* base64_challenge8; Debug("MsChapV2 authentication\n"); mschapv2_client_response = CopyBinToStr(MsChapV2_ClientResponse, 24); end = B64_Encode(buffer, mschapv2_client_response, 48); buffer[end] = '\0'; fputs("NT-Response:: ", out); fputs(buffer, out); fputs("\n", out); Debug("NT-Response:: %s\n", buffer); buffer[0] = 0; Free(mschapv2_client_response); base64_challenge8 = CopyBinToStr(challenge8, 8); end = B64_Encode(buffer, base64_challenge8 , 16); buffer[end] = '\0'; fputs("LANMAN-Challenge:: ", out); fputs(buffer, out); fputs("\n", out); Debug("LANMAN-Challenge:: %s\n", buffer); buffer[0] = 0; Free(base64_challenge8); fputs("Request-User-Session-Key: Yes\n", out); } // Start authentication fputs( ".\n", out ); fflush (out); // Request send! Zero(answer, sizeof(answer)); while (fgets(answer, sizeof(answer)-1, in)) { char* response_parameter; if (strncmp(answer, ".\n", sizeof(answer)-1 ) == 0) { break; } /* Indicates a base64 encoded structure */ response_parameter = strstr(answer, ":: "); if (!response_parameter) { char* newline; response_parameter = strstr(answer, ": "); if (!response_parameter) { continue; } response_parameter[0] ='\0'; response_parameter++; response_parameter[0] ='\0'; response_parameter++; newline = strstr(response_parameter, "\n"); if( newline ) newline[0] = '\0'; } else { response_parameter[0] ='\0'; response_parameter++; response_parameter[0] ='\0'; response_parameter++; response_parameter[0] ='\0'; response_parameter++; end = Decode64(response_parameter, response_parameter); response_parameter[end] = '\0'; } if (strncmp(answer, "Authenticated", sizeof(answer)-1 ) == 0) { if (strcmp(response_parameter, "Yes") == 0) { Debug("Authenticated!\n"); auth = true; } else if (strcmp(response_parameter, "No") == 0) { Debug("Authentication failed!\n"); auth = false; } } else if (strncmp(answer, "User-Session-Key", sizeof(answer)-1 ) == 0) { if (nt_pw_hash_hash != NULL) { BUF* Buf = StrToBin(response_parameter); Copy(nt_pw_hash_hash, Buf->Buf, 16); FreeBuf(Buf); } } } } fclose(in); fclose(out); CloseChildProcess(pid, fds); return auth; }