Exemple #1
0
// Thread that processes the accepted TCP connection
void TCPAcceptedThread(THREAD *t, void *param)
{
	TCP_ACCEPTED_PARAM *data;
	LISTENER *r;
	SOCK *s;
	CONNECTION *c;
	bool flag1;
	char tmp[128];
	// Validate arguments
	if (t == NULL || param == NULL)
	{
		return;
	}

	// Initialize
	data = (TCP_ACCEPTED_PARAM *)param;
	r = data->r;
	s = data->s;
	AddRef(r->ref);
	AddRef(s->ref);

	// Create a connection
	c = NewServerConnection(r->Cedar, s, t);

	// Register to Cedar as a transient connection
	AddConnection(c->Cedar, c);

	NoticeThreadInit(t);

	AcceptInit(s);
	StrCpy(c->ClientHostname, sizeof(c->ClientHostname), s->RemoteHostname);
	IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
	if (IS_SPECIAL_PORT(s->RemotePort) == false)
	{
		SLog(r->Cedar, "LS_LISTENER_ACCEPT", r->Port, tmp, s->RemoteHostname, s->RemotePort);
	}

	// Reception
	ConnectionAccept(c);
	flag1 = c->flag1;

	// Release
	SLog(r->Cedar, "LS_CONNECTION_END_1", c->Name);
	ReleaseConnection(c);

	// Release
	if (flag1 == false)
	{
		Debug("%s %u flag1 == false\n", __FILE__, __LINE__);
		IPToStr(tmp, sizeof(tmp), &s->RemoteIP);

		if (IS_SPECIAL_PORT(s->RemotePort) == false)
		{
			SLog(r->Cedar, "LS_LISTENER_DISCONNECT", tmp, s->RemotePort);
		}
		Disconnect(s);
	}
	ReleaseSock(s);
	ReleaseListener(r);
}
Exemple #2
0
// Search an entry
IPTABLES_ENTRY *SearchIpTables(IPTABLES_STATE *s, char *chain, IP *src_ip, IP *dest_ip, UINT mark)
{
	char ip_str1[64];
	char ip_str2[64];
	char mark_str1[64];
	char mark_str2[64];
	UINT i;
	if (s == NULL || chain == NULL || src_ip == NULL || dest_ip == NULL || mark == 0)
	{
		return NULL;
	}

	IPToStr(ip_str1, sizeof(ip_str1), src_ip);
	IPToStr(ip_str2, sizeof(ip_str2), dest_ip);
	ToStr(mark_str1, mark);
	Format(mark_str2, sizeof(mark_str2), "%x", mark);

	for (i = 0;i < LIST_NUM(s->EntryList);i++)
	{
		IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);

		if (StrCmpi(e->Chain, chain) == 0)
		{
			if (InStr(e->ConditionAndArgs, ip_str1) &&
				InStr(e->ConditionAndArgs, ip_str2) &&
				(InStr(e->ConditionAndArgs, mark_str1) || InStr(e->ConditionAndArgs, mark_str2)))
			{
				return e;
			}
		}
	}

	return NULL;
}
Exemple #3
0
// Initialize the client-side
bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT server_port, UINT server_cookie, UINT client_cookie, IP *server_ip_2)
{
	char tmp[MAX_SIZE];
	// Validate arguments
	if (a == NULL || server_key == NULL || server_ip == NULL || server_port == 0)
	{
		return false;
	}

	IPToStr(tmp, sizeof(tmp), server_ip);
	Debug("UdpAccelInitClient: server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, server_port, server_cookie, client_cookie);

	if (IsIP6(server_ip) != a->IsIPv6)
	{
		return false;
	}

	Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE);

	Copy(&a->YourIp, server_ip, sizeof(IP));
	Copy(&a->YourIp2, server_ip_2, sizeof(IP));
	a->YourPort = server_port;

	a->Now = Tick64();

	a->MyCookie = client_cookie;
	a->YourCookie = server_cookie;

	a->Inited = true;

	return true;
}
Exemple #4
0
// Jump here if there is accepted connection in the TCP
void TCPAccepted(LISTENER *r, SOCK *s)
{
	TCP_ACCEPTED_PARAM *data;
	THREAD *t;
	char tmp[MAX_SIZE];
	UINT num_clients_from_this_ip = 0;
	CEDAR *cedar;
	// Validate arguments
	if (r == NULL || s == NULL)
	{
		return;
	}

	cedar = r->Cedar;

	num_clients_from_this_ip = GetNumIpClient(&s->RemoteIP);


	IPToStr(tmp, sizeof(tmp), &s->RemoteIP);

	data = ZeroMalloc(sizeof(TCP_ACCEPTED_PARAM));
	data->r = r;
	data->s = s;

	if (r->ThreadProc == TCPAcceptedThread)
	{
		Inc(cedar->AcceptingSockets);
	}

	t = NewThread(r->ThreadProc, data);
	WaitThreadInit(t);
	Free(data);
	ReleaseThread(t);
}
Exemple #5
0
// NAT-T server IP address acquisition thread
void NatT_GetIpThread(THREAD *thread, void *param)
{
	UDP_ACCEL *a;
	char hostname[MAX_SIZE];
	static IP dummy_ip = {0};
	UINT num_retry = 0;
	// Validate arguments
	if (thread == NULL || param == NULL)
	{
		return;
	}

	a = (UDP_ACCEL *)param;

	if (IsZeroIP(&dummy_ip))
	{
		SetIP(&dummy_ip, 11, Rand8(), Rand8(), Rand8());
	}

	RUDPGetRegisterHostNameByIP(hostname, sizeof(hostname), &dummy_ip);

	while (a->NatT_Halt == false)
	{
		IP ip;
		UINT wait_time = UDP_NAT_T_GET_IP_INTERVAL;

		// Get the IP address
		bool ret = GetIP4Ex(&ip, hostname, 0, &a->NatT_Halt);

		if (ret && (IsZeroIp(&ip) == false))
		{
			char tmp[128];

			// Success to get
			Lock(a->NatT_Lock);
			{
				Copy(&a->NatT_IP, &ip, sizeof(IP));
			}
			Unlock(a->NatT_Lock);

			IPToStr(tmp, sizeof(tmp), &ip);
			Debug("NAT-T IP Address Resolved: %s = %s\n", hostname, tmp);

			a->NatT_IP_Changed = true;

			break;
		}

		// Fail to get
		num_retry++;

		wait_time = (UINT)(MIN((UINT64)UDP_NAT_T_GET_IP_INTERVAL * (UINT64)num_retry, (UINT64)UDP_NAT_T_GET_IP_INTERVAL_MAX));

		Wait(a->NatT_HaltEvent, wait_time);
	}
}
void CSingleCamDlg::OnBnClickedBtnLogin()//登录
{
	if (isLogin) //如果已经登录,就需要执行注销
	{
		NET_DVR_Logout(lUserID1);
		NET_DVR_Logout(lUserID2);
		isLogin = FALSE;
		GetDlgItem(IDC_BTN_Login)->SetWindowTextA("登录"); 
		GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(FALSE);  //播放按钮 失效
		GetDlgItem(IDC_BTN_SavePicture)->EnableWindow(FALSE);  // 抓图按钮失效
		GetDlgItem(IDC_BTN_SavePicture2)->EnableWindow(FALSE);  // 抓图按钮失效
		GetDlgItem(IDC_BTN_SaveRealData)->EnableWindow(FALSE);  // 抓图按钮失效
	} 
	else
	{
		char DeviceIP[16] = {0};
		char DeviceIP2[16] = {0};
		DWORD dwDeviceIP = 0;
		m_ctrlDeviceIP1.GetAddress(dwDeviceIP);
		CString csTemp = IPToStr(dwDeviceIP);
		sprintf_s(DeviceIP, "%s", csTemp.GetBuffer(0));

		m_ctrlDeviceIP2.GetAddress(dwDeviceIP);
		csTemp = IPToStr(dwDeviceIP);
		sprintf_s(DeviceIP2, "%s", csTemp.GetBuffer(0));

		NET_DVR_DEVICEINFO_V30 struDeviceInfo, struDeviceInfo2;
		lUserID1 = NET_DVR_Login_V30(DeviceIP, 8000, "admin", "12345", &struDeviceInfo);
		lUserID2 = NET_DVR_Login_V30(DeviceIP2, 8000, "admin", "12345", &struDeviceInfo2);
		if (lUserID1 < 0 || lUserID2 < 0) //登录失败时,其他几个按钮都需要disable
		{
			AfxMessageBox("登录失败!");
			isLogin = FALSE;
		} 
		else
		{
			isLogin = TRUE;
			GetDlgItem(IDC_BTN_Login)->SetWindowTextA("注销");  //登录成功, 变成注销
			GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(TRUE);  //播放按钮 有效
		}
	}
}
Exemple #7
0
// Add an IP address type
ITEM *CfgAddIp(FOLDER *f, char *name, struct IP *ip)
{
	char tmp[MAX_SIZE];
	// Validate arguments
	if (f == NULL || name == NULL || ip == NULL)
	{
		return NULL;
	}

	IPToStr(tmp, sizeof(tmp), ip);

	return CfgAddStr(f, name, tmp);
}
Exemple #8
0
// NAT-T server IP address acquisition thread
void NatT_GetIpThread(THREAD *thread, void *param)
{
	UDP_ACCEL *a;
	char hostname[MAX_SIZE];
	// Validate arguments
	if (thread == NULL || param == NULL)
	{
		return;
	}

	a = (UDP_ACCEL *)param;

	RUDPGetRegisterHostNameByIP(hostname, sizeof(hostname), NULL);

	while (a->NatT_Halt == false)
	{
		IP ip;

		// Get the IP address
		bool ret = GetIP4Ex(&ip, hostname, 0, &a->NatT_Halt);

		if (ret && (IsZeroIp(&ip) == false))
		{
			char tmp[128];

			// Success to get
			Lock(a->NatT_Lock);
			{
				Copy(&a->NatT_IP, &ip, sizeof(IP));
			}
			Unlock(a->NatT_Lock);

			IPToStr(tmp, sizeof(tmp), &ip);
			Debug("NAT-T IP Address Resolved: %s = %s\n", hostname, tmp);

			a->NatT_IP_Changed = true;

			break;
		}

		// Fail to get
		Wait(a->NatT_HaltEvent, UDP_NAT_T_GET_IP_INTERVAL);
	}
}
Exemple #9
0
// End the tracking of the routing table
void RouteTrackingStop(SESSION *s, ROUTE_TRACKING *t)
{
	ROUTE_ENTRY *e;
	ROUTE_TABLE *table;
	IP dns_ip;
	bool network_has_changed = false;
	bool do_not_delete_routing_entry = false;
	// Validate arguments
	if (s == NULL || t == NULL)
	{
		return;
	}

	Zero(&dns_ip, sizeof(dns_ip));

	// Remove the default gateway added by the virtual LAN card
	if (MsIsVista() == false)
	{
		if (t->DefaultGatewayByVLan != NULL)
		{
			Debug("Default Gateway by VLAN was deleted.\n");
			DeleteRouteEntry(t->DefaultGatewayByVLan);
		}

		if (t->VistaOldDefaultGatewayByVLan != NULL)
		{
			FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
		}
	}

	if (t->DefaultGatewayByVLan != NULL)
	{
		FreeRouteEntry(t->DefaultGatewayByVLan);
		t->DefaultGatewayByVLan = NULL;
	}

	if (t->VistaDefaultGateway1 != NULL)
	{
		Debug("Vista PPP Fix Route Table Deleted.\n");
		DeleteRouteEntry(t->VistaDefaultGateway1);
		FreeRouteEntry(t->VistaDefaultGateway1);

		DeleteRouteEntry(t->VistaDefaultGateway2);
		FreeRouteEntry(t->VistaDefaultGateway2);
	}

	if (MsIsNt() == false)
	{
		// Only in the case of Windows 9x, release the DHCP address of the virtual LAN card
		Win32ReleaseDhcp9x(t->VLanInterfaceId, false);
	}

	// Clear the DNS cache
	Win32FlushDnsCache();

	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		UINT i;
		ACCOUNT *a;
		for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++)
		{
			a = LIST_DATA(s->Cedar->Client->AccountList, i);
			Lock(a->lock);
			{
				SESSION *sess = a->ClientSession;
				if (sess != NULL && sess != s)
				{
					VLAN *v = sess->PacketAdapter->Param;
					if (v != NULL)
					{
						ROUTE_TRACKING *tr = v->RouteState;
						if (tr != NULL)
						{
							if (Cmp(tr->RouteToServer, t->RouteToServer, sizeof(ROUTE_ENTRY)) == 0)
							{
								do_not_delete_routing_entry = true;
							}
						}
					}
				}
			}
			Unlock(a->lock);
		}

		Lock(s->Account->lock);
	}

	if (do_not_delete_routing_entry == false)
	{
		// Delete the route that is added firstly
		if (t->RouteToServerAlreadyExists == false)
		{
			DeleteRouteEntry(t->RouteToServer);
		}

		DeleteRouteEntry(t->RouteToDefaultDns);

		DeleteRouteEntry(t->RouteToNatTServer);

		DeleteRouteEntry(t->RouteToRealServerGlobal);
	}

	FreeRouteEntry(t->RouteToDefaultDns);
	FreeRouteEntry(t->RouteToServer);
	FreeRouteEntry(t->RouteToEight);
	FreeRouteEntry(t->RouteToNatTServer);
	FreeRouteEntry(t->RouteToRealServerGlobal);
	t->RouteToDefaultDns = t->RouteToServer = t->RouteToEight =
		t->RouteToNatTServer = t->RouteToRealServerGlobal = NULL;

	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Unlock(s->Account->lock);
	}

#if	0
	// Get the current DNS server
	if (GetDefaultDns(&dns_ip))
	{
		if (IPToUINT(&t->OldDnsServer) != 0)
		{
			if (IPToUINT(&t->OldDnsServer) != IPToUINT(&dns_ip))
			{
				char s1[MAX_SIZE], s2[MAX_SIZE];
				network_has_changed = true;
				IPToStr(s1, sizeof(s1), &t->OldDnsServer);
				IPToStr(s2, sizeof(s2), &dns_ip);
				Debug("Old Dns: %s, New Dns: %s\n",
					s1, s2);
			}
		}
	}

	if (network_has_changed == false)
	{
		Debug("Network: not changed.\n");
	}
	else
	{
		Debug("Network: Changed.\n");
	}

#endif

	// Get the current routing table
	table = GetRouteTable();

	// Restore the routing table which has been removed so far
	while (e = GetNext(t->DeletedDefaultGateway))
	{
		bool restore = true;
		UINT i;
		// If the restoring routing entry is a default gateway and
		// the existing routing table contains another default gateway
		// on the interface, give up restoring the entry
		if (IPToUINT(&e->DestIP) == 0 && IPToUINT(&e->DestMask) == 0)
		{
			for (i = 0;i < table->NumEntry;i++)
			{
				ROUTE_ENTRY *r = table->Entry[i];
				if (IPToUINT(&r->DestIP) == 0 && IPToUINT(&r->DestMask) == 0)
				{
					if (r->InterfaceID == e->InterfaceID)
					{
						restore = false;
					}
				}
			}
			if (network_has_changed)
			{
				restore = false;
			}
		}

		if (restore)
		{
			// Routing table restoration
			AddRouteEntry(e);
		}

		// Memory release
		FreeRouteEntry(e);
	}

	// Release
	FreeRouteTable(table);
	ReleaseQueue(t->DeletedDefaultGateway);

	FreeRouteChange(t->RouteChange);

	Free(t);
}
Exemple #10
0
// Start tracking of the routing table
void RouteTrackingStart(SESSION *s)
{
	VLAN *v;
	ROUTE_TRACKING *t;
	UINT if_id = 0;
	ROUTE_ENTRY *e;
	ROUTE_ENTRY *dns = NULL;
	ROUTE_ENTRY *route_to_real_server_global = NULL;
	char tmp[64];
	UINT exclude_if_id = 0;
	bool already_exists = false;
	bool already_exists_by_other_account = false;
	IP eight;
	// Validate arguments
	if (s == NULL)
	{
		return;
	}

	v = (VLAN *)s->PacketAdapter->Param;
	if (v->RouteState != NULL)
	{
		return;
	}

	// Get the interface ID of the virtual LAN card
	if_id = GetInstanceId(v->InstanceName);
	Debug("[InstanceId of %s] = 0x%x\n", v->InstanceName, if_id);

	if (MsIsVista())
	{
		// The routing table by the virtual LAN card body should be
		// excluded explicitly in Windows Vista
		exclude_if_id = if_id;
	}

	// Get the route to the server
	e = GetBestRouteEntryEx(&s->ServerIP, exclude_if_id);
	if (e == NULL)
	{
		// Acquisition failure
		Debug("Failed to get GetBestRouteEntry().\n");
		return;
	}
	IPToStr(tmp, sizeof(tmp), &e->GatewayIP);
	Debug("GetBestRouteEntry() Succeed. [Gateway: %s]\n", tmp);

	// Add a route
	if (MsIsVista())
	{
		e->Metric = e->OldIfMetric;
	}
	if (AddRouteEntryEx(e, &already_exists) == false)
	{
		FreeRouteEntry(e);
		e = NULL;
	}
	Debug("already_exists: %u\n", already_exists);

	if (already_exists)
	{
		if (s->Cedar->Client != NULL && s->Account != NULL)
		{
			UINT i;
			ACCOUNT *a;
			for (i = 0;i < LIST_NUM(s->Cedar->Client->AccountList);i++)
			{
				a = LIST_DATA(s->Cedar->Client->AccountList, i);
				Lock(a->lock);
				{
					SESSION *sess = a->ClientSession;
					if (sess != NULL && sess != s)
					{
						VLAN *v = sess->PacketAdapter->Param;
						if (v != NULL)
						{
							ROUTE_TRACKING *tr = v->RouteState;
							if (tr != NULL && e != NULL)
							{
								if (Cmp(tr->RouteToServer, e, sizeof(ROUTE_ENTRY)) == 0)
								{
									already_exists_by_other_account = true;
								}
							}
						}
					}
				}
				Unlock(a->lock);
			}
		}

		if (already_exists_by_other_account)
		{
			Debug("already_exists_by_other_account = %u\n", already_exists_by_other_account);
			already_exists = false;
		}
	}

	// Get the routing table to the DNS server
	// (If the DNS server is this PC itself, there's no need to get)
	if (IsZeroIP(&s->DefaultDns) == false)
	{
		if (IsMyIPAddress(&s->DefaultDns) == false)
		{
			dns = GetBestRouteEntryEx(&s->DefaultDns, exclude_if_id);
			if (dns == NULL)
			{
				// Getting failure
				Debug("Failed to get GetBestRouteEntry DNS.\n");
			}
			else
			{
				// Add a route
				if (MsIsVista())
				{
					dns->Metric = dns->OldIfMetric;

					if (AddRouteEntry(dns) == false)
					{
						FreeRouteEntry(dns);
						dns = NULL;
					}
				}
			}
		}
	}

	if (s->IsAzureSession && IsZeroIP(&s->AzureRealServerGlobalIp) == false)
	{
		// Add also a static route to the real server in the case of via VPN Azure
		if (IsMyIPAddress(&s->AzureRealServerGlobalIp) == false)
		{
			route_to_real_server_global = GetBestRouteEntryEx(&s->AzureRealServerGlobalIp, exclude_if_id);

			if (route_to_real_server_global != NULL)
			{
				if (MsIsVista())
				{
					route_to_real_server_global->Metric = route_to_real_server_global->OldIfMetric;
				}

				if (AddRouteEntry(route_to_real_server_global) == false)
				{
					FreeRouteEntry(route_to_real_server_global);
					route_to_real_server_global = NULL;
				}
			}
		}
	}

	// Initialize
	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Lock(s->Account->lock);
	}

	t = ZeroMalloc(sizeof(ROUTE_TRACKING));
	v->RouteState = t;

	t->RouteToServerAlreadyExists = already_exists;
	t->RouteToServer = e;
	t->RouteToDefaultDns = dns;
	t->RouteToRealServerGlobal = route_to_real_server_global;
	t->VLanInterfaceId = if_id;
	t->NextTrackingTime = 0;
	t->DeletedDefaultGateway = NewQueue();
	t->OldDefaultGatewayMetric = 0x7fffffff;

	if (s->Cedar->Client != NULL && s->Account != NULL)
	{
		Unlock(s->Account->lock);
	}

	// Get the route to 8.8.8.8
	SetIP(&eight, 8, 8, 8, 8);
	t->RouteToEight = GetBestRouteEntryEx(&eight, exclude_if_id);

	// Get the current default DNS server to detect network changes
	GetDefaultDns(&t->OldDnsServer);

	// Get as soon as releasing the IP address in the case of using DHCP
	if (IsNt())
	{
		char tmp[MAX_SIZE];
		MS_ADAPTER *a;

		Format(tmp, sizeof(tmp), VLAN_ADAPTER_NAME_TAG, v->InstanceName);
		a = MsGetAdapter(tmp);

		if (a != NULL)
		{
			if (a->UseDhcp)
			{
				bool ret = Win32ReleaseAddressByGuidEx(a->Guid, 100);
				Debug("*** Win32ReleaseAddressByGuidEx = %u\n", ret);

				ret = Win32RenewAddressByGuidEx(a->Guid, 100);
				Debug("*** Win32RenewAddressByGuidEx = %u\n", ret);
			}

			MsFreeAdapter(a);
		}
	}
	else
	{
		// For Win9x
		Win32RenewDhcp9x(if_id);
	}

	// Clear the DNS cache
	Win32FlushDnsCache();

	// Detect a change in the routing table (for only supported OS)
	t->RouteChange = NewRouteChange();
	Debug("t->RouteChange = 0x%p\n", t->RouteChange);
}
Exemple #11
0
// Routing table tracking main
void RouteTrackingMain(SESSION *s)
{
	ROUTE_TRACKING *t;
	UINT64 now;
	ROUTE_TABLE *table;
	ROUTE_ENTRY *rs;
	bool changed = false;
	bool check = false;
	bool any_modified = false;
	// Validate arguments
	if (s == NULL)
	{
		return;
	}
	if (s->ClientModeAndUseVLan == false)
	{
		return;
	}

	// Get the state
	t = ((VLAN *)s->PacketAdapter->Param)->RouteState;
	if (t == NULL)
	{
		return;
	}

	// Current time
	PROBE_STR("RouteTrackingMain 1");
	now = Tick64();

	if (t->RouteChange != NULL)
	{
		if (t->NextRouteChangeCheckTime == 0 ||
			t->NextRouteChangeCheckTime <= now)
		{
			t->NextRouteChangeCheckTime = now + 1000ULL;

			check = IsRouteChanged(t->RouteChange);

			if (check)
			{
				Debug("*** Routing Table Changed ***\n");
				t->NextTrackingTime = 0;
			}
		}
	}
	if (t->NextTrackingTime != 0 && t->NextTrackingTime > now)
	{
		if (s->UseUdpAcceleration && s->UdpAccel != NULL && s->UdpAccel->NatT_IP_Changed)
		{
			// Check always if the IP address of the NAT-T server has changed
		}
		else
		{
			PROBE_STR("RouteTrackingMain 2");
			return;
		}
	}
	PROBE_STR("RouteTrackingMain 3");

	if (s->UseUdpAcceleration && s->UdpAccel != NULL)
	{
		IP nat_t_ip;

		s->UdpAccel->NatT_IP_Changed = false;

		Zero(&nat_t_ip, sizeof(nat_t_ip));

		Lock(s->UdpAccel->NatT_Lock);
		{
			Copy(&nat_t_ip, &s->UdpAccel->NatT_IP, sizeof(IP));
		}
		Unlock(s->UdpAccel->NatT_Lock);

		// Add a route to the NAT-T server
		if (IsZeroIp(&nat_t_ip) == false)
		{
			if (t->RouteToNatTServer == NULL)
			{
				if (t->RouteToEight != NULL)
				{
					ROUTE_ENTRY *e = Clone(t->RouteToEight, sizeof(ROUTE_ENTRY));
					char ip_str[64];
					char ip_str2[64];

					Copy(&e->DestIP, &nat_t_ip, sizeof(IP));
					e->Metric = e->OldIfMetric;

					IPToStr(ip_str, sizeof(ip_str), &e->DestIP);
					IPToStr(ip_str2, sizeof(ip_str2), &e->GatewayIP);

					t->RouteToNatTServer = e;

					if (AddRouteEntry(t->RouteToNatTServer))
					{
						Debug("Adding Static Route to %s via %s metric %u: ok.\n", ip_str, ip_str2, e->Metric);
					}
					else
					{
						FreeRouteEntry(t->RouteToNatTServer);
						t->RouteToNatTServer = NULL;
					}
				}
			}
		}
	}

	// Get the current routing table
	table = GetRouteTable();
	rs = t->RouteToServer;
	if (table != NULL)
	{
		UINT i;
		bool route_to_server_erased = true;
		bool is_vlan_want_to_be_default_gateway = false;
		UINT vlan_default_gatewat_metric = 0;
		UINT other_if_default_gateway_metric_min = INFINITE;

		// Get whether the routing table have been changed
		if (t->LastRoutingTableHash != table->HashedValue)
		{
			t->LastRoutingTableHash = table->HashedValue;
			changed = true;
		}

		//DebugPrintRouteTable(table);

		// Scan the routing table
		for (i = 0;i < table->NumEntry;i++)
		{
			ROUTE_ENTRY *e = table->Entry[i];

			if (rs != NULL)
			{
				if (CmpIpAddr(&e->DestIP, &rs->DestIP) == 0 &&
					CmpIpAddr(&e->DestMask, &rs->DestMask) == 0
//					&& CmpIpAddr(&e->GatewayIP, &rs->GatewayIP) == 0
//					&& e->InterfaceID == rs->InterfaceID &&
//					e->LocalRouting == rs->LocalRouting &&
//					e->Metric == rs->Metric
					)
				{
					// Routing entry to the server that added at the time of connection is found
					route_to_server_erased = false;
				}
			}

			// Search for the default gateway
			if (IPToUINT(&e->DestIP) == 0 &&
				IPToUINT(&e->DestMask) == 0)
			{
				Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n",
					e->InterfaceID, t->VLanInterfaceId);

				if (e->InterfaceID == t->VLanInterfaceId)
				{
					// The virtual LAN card think that he want to be a default gateway
					is_vlan_want_to_be_default_gateway = true;
					vlan_default_gatewat_metric = e->Metric;

					if (vlan_default_gatewat_metric >= 2 &&
						t->OldDefaultGatewayMetric == (vlan_default_gatewat_metric - 1))
					{
						// Restore because the PPP server rewrites
						// the routing table selfishly
						DeleteRouteEntry(e);
						e->Metric--;
						AddRouteEntry(e);
						Debug("** Restore metric destroyed by PPP.\n");

						any_modified = true;
					}

					// Keep this entry
					if (t->DefaultGatewayByVLan != NULL)
					{
						// Delete if there is one added last time
						FreeRouteEntry(t->DefaultGatewayByVLan);
					}

					t->DefaultGatewayByVLan = ZeroMalloc(sizeof(ROUTE_ENTRY));
					Copy(t->DefaultGatewayByVLan, e, sizeof(ROUTE_ENTRY));

					t->OldDefaultGatewayMetric = vlan_default_gatewat_metric;
				}
				else
				{
					// There are default gateway other than the virtual LAN card
					// Save the metric value of the default gateway
					if (other_if_default_gateway_metric_min > e->Metric)
					{
						// Ignore the metric value of all PPP connection in the case of Windows Vista
						if (MsIsVista() == false || e->PPPConnection == false)
						{
							other_if_default_gateway_metric_min = e->Metric;
						}
						else
						{
							// a PPP is used to Connect to the network
							// in using Windows Vista
							t->VistaAndUsingPPP = true;
						}
					}
				}
			}
		}

		if (t->VistaAndUsingPPP)
		{
			if (t->DefaultGatewayByVLan != NULL)
			{
				if (is_vlan_want_to_be_default_gateway)
				{
					if (t->VistaOldDefaultGatewayByVLan == NULL || Cmp(t->VistaOldDefaultGatewayByVLan, t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY)) != 0)
					{
						ROUTE_ENTRY *e;
						// Add the route of 0.0.0.0/1 and 128.0.0.0/1
						// to the system if the virtual LAN card should be
						// the default gateway in the case of the connection
						// using PPP in Windows Vista

						if (t->VistaOldDefaultGatewayByVLan != NULL)
						{
							FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
						}

						if (t->VistaDefaultGateway1 != NULL)
						{
							DeleteRouteEntry(t->VistaDefaultGateway1);
							FreeRouteEntry(t->VistaDefaultGateway1);

							DeleteRouteEntry(t->VistaDefaultGateway2);
							FreeRouteEntry(t->VistaDefaultGateway2);
						}

						t->VistaOldDefaultGatewayByVLan = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));

						e = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
						SetIP(&e->DestIP, 0, 0, 0, 0);
						SetIP(&e->DestMask, 128, 0, 0, 0);
						t->VistaDefaultGateway1 = e;

						e = Clone(t->DefaultGatewayByVLan, sizeof(ROUTE_ENTRY));
						SetIP(&e->DestIP, 128, 0, 0, 0);
						SetIP(&e->DestMask, 128, 0, 0, 0);
						t->VistaDefaultGateway2 = e;

						AddRouteEntry(t->VistaDefaultGateway1);
						AddRouteEntry(t->VistaDefaultGateway2);

						Debug("Vista PPP Fix Route Table Added.\n");

						any_modified = true;
					}
				}
				else
				{
					if (t->VistaOldDefaultGatewayByVLan != NULL)
					{
						FreeRouteEntry(t->VistaOldDefaultGatewayByVLan);
						t->VistaOldDefaultGatewayByVLan = NULL;
					}

					if (t->VistaDefaultGateway1 != NULL)
					{
						Debug("Vista PPP Fix Route Table Deleted.\n");
						DeleteRouteEntry(t->VistaDefaultGateway1);
						FreeRouteEntry(t->VistaDefaultGateway1);

						DeleteRouteEntry(t->VistaDefaultGateway2);
						FreeRouteEntry(t->VistaDefaultGateway2);

						any_modified = true;

						t->VistaDefaultGateway1 = t->VistaDefaultGateway2 = NULL;
					}
				}
			}
		}

		// If the virtual LAN card want to be the default gateway and
		// there is no LAN card with smaller metric of 0.0.0.0/0 than
		// the virtual LAN card, delete other default gateway entries
		// to elect the virtual LAN card as the default gateway
//		Debug("is_vlan_want_to_be_default_gateway = %u, rs = %u, route_to_server_erased = %u, other_if_default_gateway_metric_min = %u, vlan_default_gatewat_metric = %u\n",
//			is_vlan_want_to_be_default_gateway, rs, route_to_server_erased, other_if_default_gateway_metric_min, vlan_default_gatewat_metric);
		if (is_vlan_want_to_be_default_gateway && (rs != NULL && route_to_server_erased == false) &&
			other_if_default_gateway_metric_min >= vlan_default_gatewat_metric)
		{
			// Scan the routing table again
			for (i = 0;i < table->NumEntry;i++)
			{
				ROUTE_ENTRY *e = table->Entry[i];

				if (e->InterfaceID != t->VLanInterfaceId)
				{
					if (IPToUINT(&e->DestIP) == 0 &&
					IPToUINT(&e->DestMask) == 0)
					{
						char str[64];
						// Default gateway is found
						ROUTE_ENTRY *r = ZeroMalloc(sizeof(ROUTE_ENTRY));

						Copy(r, e, sizeof(ROUTE_ENTRY));

						// Put in the queue
						InsertQueue(t->DeletedDefaultGateway, r);

						// Delete this gateway entry once
						DeleteRouteEntry(e);

						IPToStr(str, sizeof(str), &e->GatewayIP);
						Debug("Default Gateway %s Deleted.\n", str);

						any_modified = true;
					}
				}
			}
		}

		if (rs != NULL && route_to_server_erased)
		{
			// Physical entry to the server has disappeared
			Debug("Route to Server entry ERASED !!!\n");

			// Forced disconnection (reconnection enabled)
			s->RetryFlag = true;
			s->Halt = true;
		}

		// Release the routing table
		FreeRouteTable(table);
	}

	// Set the time to perform the next track
	if (t->NextTrackingTimeAdd == 0 || changed)
	{
		t->NextTrackingTimeAdd = TRACKING_INTERVAL_INITIAL;
	}
	else
	{
		UINT64 max_value = TRACKING_INTERVAL_MAX;
		if (t->RouteChange != NULL)
		{
			max_value = TRACKING_INTERVAL_MAX_RC;
		}

		t->NextTrackingTimeAdd += TRACKING_INTERVAL_ADD;

		if (t->NextTrackingTimeAdd >= max_value)
		{
			t->NextTrackingTimeAdd = max_value;
		}
	}
	//Debug("t->NextTrackingTimeAdd = %I64u\n", t->NextTrackingTimeAdd);
	t->NextTrackingTime = now + t->NextTrackingTimeAdd;

	if (any_modified)
	{
		// Clear the DNS cache
		Win32FlushDnsCache();
	}
}
Exemple #12
0
// 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;
}