Ver Fonte

First upload

+Added comments
Deben Oldert há 10 anos atrás
pai
commit
cf6ed66d7e
2 ficheiros alterados com 245 adições e 0 exclusões
  1. 213 0
      ARS Server/dllmain.cpp
  2. 32 0
      ARS Server/stdafx.h

+ 213 - 0
ARS Server/dllmain.cpp

@@ -0,0 +1,213 @@
+//Set includes
+#include <iostream>
+#include <fstream>
+
+#include <Windows.h>
+#include <Authif.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctime>
+#include <string>
+#include "WinHttpClient.h"
+#include <rapidjson\document.h>
+#include "stdafx.h"
+
+//#define _CRT_SECURE_NO_WARNINGS
+void logger(const char * msg) //Logger function ==> Write to a log file
+{
+	FILE * fp = fopen("C:/Temp/NPS.log.txt", "a");
+	if (fp)
+	{
+		fprintf(fp, "%s\n", msg);
+		fclose(fp);
+	}
+}
+
+DWORD WINAPI RadiusExtensionProcess2(
+	_Inout_  PRADIUS_EXTENSION_CONTROL_BLOCK pECB //The famous function
+	)
+{
+	if (pECB != NULL) //Check if we got some data from NPS
+	{
+		if (pECB->rcRequestType == rcAccessRequest) //Check if the request is a access request
+		{
+			RADIUS_ATTRIBUTE_ARRAY * pAR = pECB->GetRequest(pECB); //Get the attribute array
+			if (pAR != NULL) //Check if the attribute array is not empty
+			{
+				//Initialize some variables
+				char * username = "";
+				char * password = "";
+				char * uniqueId = "";
+				char * clientIp = "";
+
+				//Get the size of the attribute array
+				DWORD size = pAR->GetSize(pAR);
+
+				//Pre-init the attribute pointer
+				const RADIUS_ATTRIBUTE * pRA;
+
+				//Loop through each object in attribute array
+				for (DWORD iAR = 0; iAR < size; iAR++)
+				{
+					//Get the attribute from the array
+					pRA = pAR->AttributeAt(pAR, iAR);
+					if (pRA != NULL) //Check if the attribute is not empty
+					{
+						if(pRA->dwAttrType == ratUserName) //Get the username
+						{
+							username = (char *) pRA->lpValue;
+						}
+						if(pRA->dwAttrType == ratUniqueId) //Get the request ID
+						{
+							uniqueId = (char *) pRA->dwValue;
+						}
+						if(pRA->dwAttrType == ratUserPassword) //Get the password (can be empty or "")
+						{
+							password = (char *) pRA->lpValue;
+						}
+						if(pRA->dwAttrType == ratCallingStationId) //Get the source ip address
+						{
+							clientIp = (char *) pRA->dwValue;
+						}
+					}
+				}
+
+				//Write the result to the log file
+				char buft[2048];
+				sprintf(buft, "Recieved Request (ID:%d) for user: %s, pass: %s",uniqueId, username, password);
+				logger(buft);
+
+				//Init a post request
+				WinHttpClient post(L"http://192.168.2.240:8080/Implementation/SAS");
+
+				//Create the request json string
+				char dat[2000];
+				sprintf(dat, "{\"function\":\"authenticate\",\"requestId\":%d,\"username\":\"%s\",\"password\":\"%s\"}", uniqueId, username, password);
+				
+				//Cast from char to string
+				string data = string(dat);
+
+				//Set request data (send json)
+				post.SetAdditionalDataToSend((BYTE *)data.c_str(), (int) data.size());
+
+				//Set request headers
+				wchar_t szSize[50] = L"";
+				swprintf_s(szSize, L"%d", data.size());
+				wstring headers = L"Content-Length: ";
+				headers += szSize;
+				headers += L"\r\nContent-Type: application/x-www-form-urlencoded\r\n";
+				post.SetAdditionalRequestHeaders(headers);
+
+				//Set max timeout
+				post.SetTimeouts(30000U, 30000U, 30000U, 30000U);
+
+				//Execute the post request
+				if(!post.SendHttpRequest(L"POST", true)) //If it failed log it
+				{
+					char answer[2048];
+					sprintf(answer, "POST FAILED from: %s for id: %d, user: %s", clientIp, uniqueId, username);
+					logger(answer);
+					pECB->SetResponseType(pECB, rcAccessReject);
+					return NO_ERROR;
+				}
+				else
+				{
+					//Set the time for our timeout loop
+					int timeout = 30;
+
+					//Pre-init the response var
+					char * response;
+
+					//Our timeout loop
+					for(int i=1; i<=timeout; i++)
+					{
+						//Check if we received some content
+						if((int) post.GetRawResponseReceivedContentLength() > 0)
+						{
+							//YEAHHH!! We received a response
+							response = (char *) post.GetRawResponseContent();
+							break; //Exit the loop
+						}
+						else if(i >= timeout)
+						{
+							//OOPS!! Still no response after our time out time
+							pECB->SetResponseType(pECB, rcAccessReject); //Set our RADIUS response to reject
+							return NO_ERROR; //Exit the complete function
+						}
+						else //Still no response and within the timeout
+						{
+							//Sleep for 1 second (1000 miliseconds)
+							Sleep(1000);
+							continue; //Continue the loop
+						}
+					}
+
+					//Finally out of the loop
+
+					//Check again if response is not empty
+					if(sizeof(response) == 0)
+					{
+						//If so, exit
+						pECB->SetResponseType(pECB, rcAccessReject); //Set our RADIUS response to reject
+						return NO_ERROR; //Exit the complete function
+					}
+
+					//Produce a json document from the received content
+					rapidjson::Document json;
+					json.Parse(response);
+
+					//Pre-init var
+					int code;
+
+					//Check if the received json contains the "result" key
+					if(json.HasMember("result"))
+					{
+						//If so, Get it as an int
+						if(json["result"].IsInt())
+						{
+							//Write it to the code var
+							code = json["result"].GetInt();
+						}
+						else //If it is not an int or it failed deny the request
+						{
+							pECB->SetResponseType(pECB, rcAccessReject); //Set our RADIUS response to reject
+							return NO_ERROR; //Exit the complete function
+						}
+					}
+					else //If the result key doesn't exist, deny the request
+					{
+						pECB->SetResponseType(pECB, rcAccessReject); //Set our RADIUS response to reject
+						return NO_ERROR; //Exit the complete function
+					}
+
+					//If the result code is 0 Allow the request
+					if(code == 0)
+					{
+						char out[5000];
+						sprintf(out, "Login SUCCES from %s for id: %d, user: %s", clientIp, uniqueId, username);
+						logger(out);
+						pECB->SetResponseType(pECB, rcAccessAccept); //Set our RADIUS response to accept
+					}
+					else //Log every other result code
+					{
+						char out[5000];
+						sprintf(out, "Login FAILED from %s for id: %d, user: %s | result==> code: %d, text: %s", clientIp, uniqueId, username, code, json["resultText"].GetString());
+						logger(out);
+						pECB->SetResponseType(pECB, rcAccessReject); //Set our RADIUS response to reject
+					}
+				
+				}
+			
+			}
+		}
+		else if (pECB->rcRequestType == rcAccountingRequest) //If request type is an accounting request
+		{
+			pECB->SetResponseType(pECB, rcAccountingResponse); //Then just answer it
+		}
+		else //If we get another request
+		{
+			pECB->SetResponseType(pECB, rcUnknown); //We don't know what to do with it
+		}
+	}
+	return NO_ERROR; //Exit the complete function
+}

+ 32 - 0
ARS Server/stdafx.h

@@ -0,0 +1,32 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+
+#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+#ifdef NPS_DLL_EXAMPLE_EXPORTS
+#define NPS_DLL_EXAMPLE_API __declspec(dllexport)
+#else
+#define NPS_DLL_EXAMPLE_API __declspec(dllimport)
+#endif
+#include <Authif.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	DWORD NPS_DLL_EXAMPLE_API WINAPI RadiusExtensionProcess2(
+		_Inout_  PRADIUS_EXTENSION_CONTROL_BLOCK pECB
+		);
+#ifdef __cplusplus
+}
+#endif
+
+//void logger(const char * msg);
+