Esempio n. 1
0
        /// <summary>
        /// Parses a packet and gets a response packet from the handler
        /// </summary>
        /// <param name="packetHandler"></param>
        /// <param name="sharedSecret"></param>
        /// <param name="packetBytes"></param>
        /// <param name="remoteEndpoint"></param>
        /// <returns></returns>
        internal IRadiusPacket GetResponsePacket(IPacketHandler packetHandler, string sharedSecret, byte[] packetBytes, IPEndPoint remoteEndpoint)
        {
            var requestPacket = RadiusPacketParser.Parse(packetBytes, Encoding.UTF8.GetBytes(sharedSecret));

            //TODO log output here
            //$"Received {requestPacket.Code} from {remoteEndpoint} Id={requestPacket.Identifier}"

            //if logger in debug mode
            //DumpPacket(requestPacket);

            //TODO log output here
            //packetBytes.ToHexString()

            // Handle status server requests in server outside packet handler
            if (requestPacket.Code == PacketCode.StatusServer)
            {
                var responseCode = ServerType == RadiusServerType.Authentication ? PacketCode.AccessAccept : PacketCode.AccountingResponse;

                //TODO log output here
                //$"Sending {responseCode} for StatusServer request from {remoteEndpoint}"

                return(requestPacket.CreateResponsePacket(responseCode));
            }

            //TODO log output here
            //$"Handling packet for remote ip {remoteEndpoint.Address} with {packetHandler.GetType()}"

            var sw             = Stopwatch.StartNew();
            var responsePacket = packetHandler.HandlePacket(requestPacket);

            sw.Stop();

            //TODO log output here
            //$"{remoteEndpoint} Id={responsePacket.Identifier}, Received {responsePacket.Code} from handler in {sw.ElapsedMilliseconds}ms"

            //TODO log output here
            //if (sw.ElapsedMilliseconds >= 5000)
            //$"Slow response for Id {responsePacket.Identifier}, check logs"

            if (requestPacket.Attributes.ContainsKey("Proxy-State"))
            {
                responsePacket.Attributes.Add("Proxy-State", requestPacket.Attributes.SingleOrDefault(o => o.Key == "Proxy-State").Value);
            }

            return(responsePacket);
        }
        /// <summary>
        /// Used to handle the packets asynchronously
        /// </summary>
        /// <param name="remoteEndpoint"></param>
        /// <param name="packetBytes"></param>
        private void HandlePacket(IPEndPoint remoteEndpoint, Byte[] packetBytes)
        {
            try
            {
                _logger.LogDebug($"Received packet from {remoteEndpoint}, Concurrent handlers count: {Interlocked.Increment(ref _concurrentHandlerCount)}");

                if (_packetHandlerRepository.TryGetHandler(remoteEndpoint.Address, out var handler))
                {
                    var responsePacket = GetResponsePacket(handler.packetHandler, handler.sharedSecret, packetBytes, remoteEndpoint);
                    if (responsePacket != null)
                    {
                        SendResponsePacket(responsePacket, remoteEndpoint);
                    }
                }
                else
                {
                    _logger.LogError($"No packet handler found for remote ip {remoteEndpoint}");
                    var packet = _radiusPacketParser.Parse(packetBytes, Encoding.UTF8.GetBytes("wut"));
                    DumpPacket(packet);
                }
            }
            catch (Exception ex) when(ex is ArgumentException || ex is OverflowException)
            {
                _logger.LogWarning($"Ignoring malformed(?) packet received from {remoteEndpoint}", ex);
                _logger.LogDebug(packetBytes.ToHexString());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Failed to receive packet from {remoteEndpoint}");
                _logger.LogDebug(packetBytes.ToHexString());
            }
            finally
            {
                Interlocked.Decrement(ref _concurrentHandlerCount);
            }
        }
        /// <summary>
        /// Parses a packet and gets a response packet from the handler
        /// </summary>
        internal void ParseAndProcess(byte[] packetBytes, IPEndPoint remoteEndpoint)
        {
            var requestPacket = _radiusPacketParser.Parse(packetBytes, Encoding.UTF8.GetBytes(_configuration.RadiusSharedSecret));

            _logger.Debug($"Received {requestPacket.Code} from {remoteEndpoint} Id={requestPacket.Identifier}");

            if (_cacheService.IsRetransmission(requestPacket, remoteEndpoint))
            {
                _logger.Debug($"Retransmissed request from {remoteEndpoint} Id={requestPacket.Identifier}, ignoring");
                return;
            }

            var request = new PendingRequest {
                RemoteEndpoint = remoteEndpoint, RequestPacket = requestPacket
            };

            Task.Run(() => _router.HandleRequest(request));
        }
Esempio n. 4
0
        /// <summary>
        /// Authenticate request at Remote Radius Server with user-name and password
        /// </summary>
        private async Task <PacketCode> ProcessRadiusAuthentication(PendingRequest request, ClientConfiguration clientConfig)
        {
            try
            {
                //sending request as is to Remote Radius Server
                using (var client = new RadiusClient(clientConfig.ServiceClientEndpoint, _logger))
                {
                    _logger.Debug($"Sending AccessRequest message with id={{id}} to Remote Radius Server {clientConfig.NpsServerEndpoint}", request.RequestPacket.Identifier);

                    var requestBytes = _packetParser.GetBytes(request.RequestPacket);
                    var response     = await client.SendPacketAsync(request.RequestPacket.Identifier, requestBytes, clientConfig.NpsServerEndpoint, TimeSpan.FromSeconds(5));

                    if (response != null)
                    {
                        var responsePacket = _packetParser.Parse(response, request.RequestPacket.SharedSecret, request.RequestPacket.Authenticator);
                        _logger.Debug("Received {code:l} message with id={id} from Remote Radius Server", responsePacket.Code.ToString(), responsePacket.Identifier);

                        if (responsePacket.Code == PacketCode.AccessAccept)
                        {
                            var userName = request.RequestPacket.UserName;
                            _logger.Information($"User '{{user:l}}' credential and status verified successfully at {clientConfig.NpsServerEndpoint}", userName);
                        }

                        request.ResponsePacket = responsePacket;
                        return(responsePacket.Code); //Code received from remote radius
                    }
                    else
                    {
                        _logger.Warning("Remote Radius Server did not respond on message with id={id}", request.RequestPacket.Identifier);
                        return(PacketCode.AccessReject); //reject by default
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Radius authentication error");
            }

            return(PacketCode.AccessReject); //reject by default
        }
Esempio n. 5
0
        /// <summary>
        /// Authenticate request at Network Policy Server with user-name and password
        /// </summary>
        private PacketCode ProcessRadiusAuthentication(PendingRequest request)
        {
            try
            {
                //sending request as is to Network Policy Server
                using (var client = new RadiusClient(_configuration.ServiceClientEndpoint, _logger))
                {
                    _logger.Debug($"Sending Access-Request message with Id={request.RequestPacket.Identifier} to Network Policy Server {_configuration.NpsServerEndpoint}");

                    var requestBytes = _packetParser.GetBytes(request.RequestPacket);
                    var response     = client.SendPacketAsync(request.RequestPacket.Identifier, requestBytes, _configuration.NpsServerEndpoint, TimeSpan.FromSeconds(5)).Result;

                    if (response != null)
                    {
                        var responsePacket = _packetParser.Parse(response, request.RequestPacket.SharedSecret, request.RequestPacket.Authenticator);
                        _logger.Debug($"Received {responsePacket.Code} message with Id={responsePacket.Identifier} from Network Policy Server");

                        if (responsePacket.Code == PacketCode.AccessAccept)
                        {
                            var userName = request.RequestPacket.UserName;
                            _logger.Information($"User '{userName}' credential and status verified successfully at {_configuration.NpsServerEndpoint}");
                        }

                        request.ResponsePacket = responsePacket;
                        return(responsePacket.Code); //Code received from NPS
                    }
                    else
                    {
                        _logger.Warning($"Network Policy Server did not respond on message with Id={request.RequestPacket.Identifier}");
                        return(PacketCode.AccessReject); //reject by default
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Radius authentication error");
            }

            return(PacketCode.AccessReject); //reject by default
        }
Esempio n. 6
0
        /// <summary>
        /// Parses a packet and gets a response packet from the handler
        /// </summary>
        internal void ParseAndProcess(byte[] packetBytes, IPEndPoint remoteEndpoint)
        {
            IPEndPoint proxyEndpoint = null;

            if (IsProxyProtocol(packetBytes, out var sourceEndpoint, out var requestWithoutProxyHeader))
            {
                packetBytes    = requestWithoutProxyHeader;
                proxyEndpoint  = remoteEndpoint;
                remoteEndpoint = sourceEndpoint;
            }

            ClientConfiguration clientConfiguration = null;

            if (RadiusPacketNasIdentifierParser.TryParse(packetBytes, out var nasIdentifier))
            {
                clientConfiguration = _serviceConfiguration.GetClient(nasIdentifier);
            }
            if (clientConfiguration == null)
            {
                clientConfiguration = _serviceConfiguration.GetClient(remoteEndpoint.Address);
            }

            if (clientConfiguration == null)
            {
                _logger.Warning("Received packet from unknown client {host:l}:{port}, ignoring", remoteEndpoint.Address, remoteEndpoint.Port);
                return;
            }

            var requestPacket    = _radiusPacketParser.Parse(packetBytes, Encoding.UTF8.GetBytes(clientConfiguration.RadiusSharedSecret));
            var isRetransmission = _cacheService.IsRetransmission(requestPacket, remoteEndpoint);

            if (isRetransmission)
            {
                _logger.Debug("Retransmissed request from {host:l}:{port} id={id} client '{client:l}', ignoring", remoteEndpoint.Address, remoteEndpoint.Port, requestPacket.Identifier, clientConfiguration.Name);
                return;
            }

            if (proxyEndpoint != null)
            {
                if (requestPacket.Code == PacketCode.StatusServer)
                {
                    _logger.Information("Received {code:l} from {host:l}:{port} proxied by {proxyhost:l}:{proxyport} id={id} client '{client:l}'", requestPacket.Code.ToString(), remoteEndpoint.Address, remoteEndpoint.Port, proxyEndpoint.Address, proxyEndpoint.Port, requestPacket.Identifier, clientConfiguration.Name);
                }
                else
                {
                    _logger.Information("Received {code:l} from {host:l}:{port} proxied by {proxyhost:l}:{proxyport} id={id} user='******' client '{client:l}'", requestPacket.Code.ToString(), remoteEndpoint.Address, remoteEndpoint.Port, proxyEndpoint.Address, proxyEndpoint.Port, requestPacket.Identifier, requestPacket.UserName, clientConfiguration.Name);
                }
            }
            else
            {
                if (requestPacket.Code == PacketCode.StatusServer)
                {
                    _logger.Debug("Received {code:l} from {host:l}:{port} id={id} client '{client:l}'", requestPacket.Code.ToString(), remoteEndpoint.Address, remoteEndpoint.Port, requestPacket.Identifier, clientConfiguration.Name);
                }
                else
                {
                    _logger.Information("Received {code:l} from {host:l}:{port} id={id} user='******' client '{client:l}'", requestPacket.Code.ToString(), remoteEndpoint.Address, remoteEndpoint.Port, requestPacket.Identifier, requestPacket.UserName, clientConfiguration.Name);
                }
            }


            var request = new PendingRequest {
                RemoteEndpoint = remoteEndpoint, ProxyEndpoint = proxyEndpoint, RequestPacket = requestPacket
            };

            Task.Run(async() => await _router.HandleRequest(request, clientConfiguration));
        }