Esempio n. 1
0
        static void TcpIpPerformance()
        {
            long tableTime, processTimeTotal, sidTimeTotal;

            var sw = new Stopwatch();

            sw.Start();

            var tcpTable = TcpTable.GetAllTcpConnections();

            sw.Stop();
            tableTime = sw.ElapsedMilliseconds;

            var itemCount = tcpTable.Length;
            //=====================================================
            var processPaths = new string[tcpTable.Length];

            sw.Reset();
            sw.Start();
            for (int i = 0; i < tcpTable.Length; i++)
            {
                if (tcpTable[i].owningPid != 0)
                {
                    processPaths[i] = ProcessPath.GetProcessPath((uint)tcpTable[i].owningPid);
                }
                else
                {
                    processPaths[i] = "SystemIdle";
                }
            }
            sw.Stop();
            processTimeTotal = sw.ElapsedMilliseconds;

            //=====================================================
            var processSid = new string[tcpTable.Length];
            var myProcess  = Process.GetCurrentProcess();

            sw.Reset(); sw.Start();
            //for (int i = 0; i < tcpTable.Length; i++)
            //{
            //    if (processPaths[i] != "")
            //    {
            //        processSid[i] = ProcessUser.sidFromProcess((uint)tcpTable[i].owningPid);
            //    }
            //}
            Action <string> loggerSample = new Action <string>((text) => Console.WriteLine(text));

            Console.WriteLine(ProcessUserSid.sidFromProcess((uint)myProcess.Id, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess((uint)myProcess.Id, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess((uint)myProcess.Id, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess((uint)myProcess.Id, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess((uint)myProcess.Id, loggerSample));

            sw.Stop();
            Console.WriteLine("Only fast sid: " + sw.ElapsedMilliseconds + "ms");

            sw.Reset(); sw.Start();
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));
            Console.WriteLine(ProcessUserSid.sidFromProcess(4, loggerSample));

            sw.Stop();
            sidTimeTotal = sw.ElapsedMilliseconds;

            Console.WriteLine($"Results\n======\nTcpTable: {tableTime}ms\nPaths: {processTimeTotal}ms\nSids: {sidTimeTotal}ms");
        }
        //  Class Functions:
        // =================================================


        public HTTPTaskResult StartListener(IPAddress ip, int port, Func <bool> isCancelled)
        {
            HTTPTaskResult result
                = HTTPTaskResult.Fail(HTTPResultEnum.NOTOKEN_ERROR, "init");

            TcpListener tcpServer = new TcpListener(ip, port);

            tcpServer.Start();

            _actual_port = ((IPEndPoint)tcpServer.LocalEndpoint).Port;

            // Timeout for accepting client -> Just check if pending (https://stackoverflow.com/a/3315200)
            int acceptTimePassedMS = 0;

            acceptTimePassedMS = WaitForTcpClient(isCancelled, tcpServer, acceptTimePassedMS);

            if (acceptTimePassedMS >= AcceptTimeout.TotalMilliseconds || isCancelled())
            {
                result = HTTPTaskResult
                         .Fail(HTTPResultEnum.NOTOKEN_ERROR,
                               "Accept socket timeout", resultObj: isCancelled());
            }
            else
            {
                TcpClient client = tcpServer.AcceptTcpClient();
                client.ReceiveTimeout = (int)TotalRequestTimeout.TotalMilliseconds;
                client.SendTimeout    = (int)TotalResponseTimeout.TotalMilliseconds;

                NetworkStream ns = client.GetStream();
                try
                {
                    if (!ns.CanTimeout)
                    {
                        result = HTTPTaskResult
                                 .Fail(HTTPResultEnum.NOTOKEN_ERROR,
                                       "Networkstream can't timeout!", resultObj: isCancelled());
                    }
                    else
                    {
                        ns.ReadTimeout  = client.ReceiveTimeout;
                        ns.WriteTimeout = client.SendTimeout;

                        int    bytesRecieved = 0;
                        byte[] RequestBuffer = new byte[BufferSize];
                        string requestData   = RecieveHTTPRequest(isCancelled, ns, ref bytesRecieved, RequestBuffer);

                        if (!requestData.EndsWith(HTTPHeadersEnd))
                        {
                            result = HTTPTaskResult
                                     .Fail(HTTPResultEnum.NOTOKEN_ERROR,
                                           "Error getting a valid HTTP request", resultObj: isCancelled());
                        }
                        else
                        {
                            bool validReq = true;
                            foreach (string item in findInRequest)
                            {
                                if (!requestData.Contains(item.ToLower()))
                                {
                                    validReq = false;
                                    break;
                                }
                            }

                            if (!validReq)
                            {
                                // Because we also check Agent header here, so from this point it is all security
                                result = HTTPTaskResult
                                         .Fail(HTTPResultEnum.TOKEN_AUTH_ERROR,
                                               "Didn't find all required text in request:\n" + requestData, resultObj: isCancelled());
                            }
                            else
                            {
                                int pid = pidFromConnection(client);
                                if (pid < 0)
                                {
                                    result = HTTPTaskResult
                                             .Fail(HTTPResultEnum.TOKEN_AUTH_ERROR,
                                                   "Can't find token req PID owner", resultObj: isCancelled());
                                }
                                else
                                {
                                    LocalGroupsAndUsers users = new LocalGroupsAndUsers();
                                    string processPath        = ProcessPath.GetProcessPath((uint)pid);
                                    string userSid            = ProcessUserSid.sidFromProcess((uint)pid, (s) => { });
                                    string userName           = users.getUserName(userSid);

                                    if (processPath == "" || userName == "" || userSid == "")
                                    {
                                        result = HTTPTaskResult
                                                 .Fail(HTTPResultEnum.TOKEN_AUTH_ERROR,
                                                       "Error getting process owner information", resultObj: isCancelled());
                                    }
                                    else
                                    {
                                        Properties.Settings config = Properties.Settings.Default;
                                        bool isCallerAllowed       =
                                            config.AllowedClientUsernames.ToLower().Contains(userName.ToLower()) &&
                                            config.AllowedClientPaths.ToLower().Contains(processPath.ToLower()) &&
                                            !isCancelled();

                                        if (!isCallerAllowed)
                                        {
                                            result = HTTPTaskResult
                                                     .Fail(HTTPResultEnum.TOKEN_AUTH_ERROR,
                                                           string.Format(
                                                               "Token acces denied problem!\nProcess: {0}\nUserSid: {1}\nUserName: {2}",
                                                               processPath, userSid, userName
                                                               ),
                                                           resultObj: isCancelled());
                                        }
                                        else
                                        {
                                            byte[] responseBuffer = CreateTokenHTTPResponse(DataToServe);

                                            Stopwatch sendTimer = new Stopwatch();
                                            sendTimer.Start();
                                            ns.Write(responseBuffer, 0, responseBuffer.Length);
                                            sendTimer.Stop();

                                            if (sendTimer.ElapsedMilliseconds >= ns.WriteTimeout)
                                            {
                                                // Because maybe he got the token and stopped responding (reading) => TOKEN_AUTH_ERROR
                                                result = HTTPTaskResult
                                                         .Fail(HTTPResultEnum.TOKEN_AUTH_ERROR,
                                                               "Error sending response, got timeout.", resultObj: isCancelled());
                                            }
                                            else
                                            {
                                                result = HTTPTaskResult.Success(HTTPResultEnum.SUCCESS, "Token sent!");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    result = HTTPTaskResult
                             .Fail(HTTPResultEnum.TOKEN_AUTH_ERROR,
                                   "Error in token process", resultObj: isCancelled(), error: ex);
                }
                finally
                {
                    ns.Close();
                    client.Close();
                    tcpServer.Stop();
                }
            }

            return(result);
        }