示例#1
0
        public TestSession(IMbbsHost host) : base("test")
        {
            SendToClientMethod = Send;
            OutputEnabled      = true;

            CurrentModule = host.GetModule("MBBSEMU");

            SessionType  = EnumSessionType.Test;
            SessionState = EnumSessionState.EnteringModule;
        }
示例#2
0
        public TestSession(IMbbsHost host, ITextVariableService textVariableService) : base(host, "test", EnumSessionState.EnteringModule, textVariableService)
        {
            SendToClientMethod = Send;
            OutputEnabled      = true;

            CurrentModule = host?.GetModule("MBBSEMU");

            SessionType = EnumSessionType.Test;

            Username = "******";
            Email    = "*****@*****.**";
        }
示例#3
0
        /// <summary>
        ///     Scans incoming Rlogin bytes looking for the first three nulls, accumulating them
        ///     in the rloginStrings collection. Once found, picks out the first non-empty string
        ///     as the UserName and sets the proper Session states.
        /// </summary>
        /// <returns>Returns true when rlogin analysis has completed</returns>
        private bool ProcessIncomingByte(byte b)
        {
            if (b != 0)
            {
                memoryStream.WriteByte(b);
                return(false);
            }

            rloginStrings.Add(Encoding.ASCII.GetString(memoryStream.ToArray()));
            memoryStream.SetLength(0);

            if (rloginStrings.Count < 3 || rloginStrings.Count(s => !string.IsNullOrEmpty(s)) < 2)
            {
                return(false);
            }

            // we have 3 strings, pick out username and launch appropriately
            Username = rloginStrings.First(s => !string.IsNullOrEmpty(s));

            rloginStrings.Clear();

            _logger.Info($"Rlogin For User: {Username}");

            if (!string.IsNullOrEmpty(ModuleIdentifier))
            {
                CurrentModule = _host.GetModule(ModuleIdentifier);
                SessionState  = EnumSessionState.RloginEnteringModule;
            }
            else
            {
                SessionState = EnumSessionState.LoginRoutines;
            }

            //Send 0 byte to ACK
            Send(new byte[] { 0x0 });

            return(true);
        }
示例#4
0
        protected override (byte[], int) ProcessIncomingClientData(byte[] clientData, int bytesReceived)
        {
            if (SessionState != EnumSessionState.Negotiating)
            {
                return(clientData, bytesReceived);
            }

            var rloginStrings = Encoding.ASCII.GetString(clientData, 0, bytesReceived).Split('\0', StringSplitOptions.RemoveEmptyEntries);

            if (rloginStrings.Length == 0)
            {
                CloseSocket($"Invalid rlogin negotiation, didn't receive null terminated strings");
                return(null, 0);
            }
            // all we care about is the username, ignore the other fields
            Username = rloginStrings[0];

            _logger.Info($"Rlogin For User: {Username}");

            if (!string.IsNullOrEmpty(ModuleIdentifier))
            {
                CurrentModule = _host.GetModule(ModuleIdentifier);
                SessionState  = EnumSessionState.EnteringModule;
            }
            else
            {
                SessionState = EnumSessionState.MainMenuDisplay;
            }

            //Send 0 byte to ACK
            Send(new byte[] { 0x0 });

            // ignore any extraneous data, since the client should wait until we ack back with
            // the zero byte
            return(null, 0);
        }
示例#5
0
        /// <summary>
        ///     Thread to handle receiving data from the client
        /// </summary>
        private void ReceiveWorker()
        {
            while (SessionState != EnumSessionState.LoggedOff && _rloginConnection.IsConnected())
            {
                var bytesReceived = _rloginConnection.Receive(socketReceiveBuffer, SocketFlags.None, out var socketState);
                ValidateSocketState(socketState);

                if (bytesReceived == 0)
                {
                    continue;
                }

                //Parse RLogin Information
                if (SessionState == EnumSessionState.Negotiating && bytesReceived > 2 &&
                    socketReceiveBuffer[0] == 0x0)
                {
                    var usernameLength  = 0;
                    var startingOrdinal = 1;

                    if (socketReceiveBuffer[1] == 0)
                    {
                        startingOrdinal++;
                    }

                    ReadOnlySpan <byte> bufferSpan = socketReceiveBuffer;

                    //Find End of Username
                    for (var i = startingOrdinal; i < bytesReceived; i++)
                    {
                        if (socketReceiveBuffer[i] != 0x0)
                        {
                            continue;
                        }
                        usernameLength = i - startingOrdinal;
                        break;
                    }

                    //Send 0 byte to ACK
                    Send(new byte[] { 0x0 });
                    Username = Encoding.ASCII.GetString(bufferSpan.Slice(startingOrdinal, usernameLength));

                    _logger.Info($"Rlogin For User: {Username}");

                    if (!string.IsNullOrEmpty(ModuleIdentifier))
                    {
                        CurrentModule = _host.GetModule(ModuleIdentifier);
                        SessionState  = EnumSessionState.EnteringModule;
                    }
                    else
                    {
                        SessionState = EnumSessionState.MainMenuDisplay;
                    }

                    continue;
                }

                //Enqueue the incoming bytes for processing
                for (var i = 0; i < bytesReceived; i++)
                {
                    DataFromClient.Add(socketReceiveBuffer[i]);
                }

                Thread.Sleep(1);
            }

            //Cleanup if the connection was dropped
            SessionState = EnumSessionState.LoggedOff;

            //Dispose the socket connection
            _rloginConnection.Dispose();
        }
示例#6
0
        /// <summary>
        ///     Scans incoming Rlogin bytes looking for the first three nulls, accumulating them
        ///     in the rloginStrings collection. Once found, picks out the first non-empty string
        ///     as the UserName and sets the proper Session states.
        /// </summary>
        /// <returns>Returns true when rlogin analysis has completed</returns>
        private bool ProcessIncomingByte(byte b)
        {
            if (b != 0)
            {
                memoryStream.WriteByte(b);
                return(false);
            }

            rloginStrings.Add(Encoding.ASCII.GetString(memoryStream.ToArray()));
            memoryStream.SetLength(0);

            if (rloginStrings.Count < 3 || rloginStrings.Count(s => !string.IsNullOrEmpty(s)) < 2)
            {
                return(false);
            }

            //Check to see if there is an available channel
            if (_channelDictionary.Count > _configuration.BBSChannels)
            {
                var channelFullMsg =
                    $"\r\n|RED||B|{_configuration.BBSTitle} has reached the maximum number of users: {_configuration.BBSChannels} -- Please try again later.\r\n|RESET|"
                    .EncodeToANSIArray();
                Send(channelFullMsg);
                SessionState = EnumSessionState.LoggedOff;
                return(false);
            }

            //Check if user is already logged in
            if (_channelDictionary.Values.Any(s => string.Equals(s.Username,
                                                                 rloginStrings.First(s => !string.IsNullOrEmpty(s)), StringComparison.CurrentCultureIgnoreCase)))
            {
                _logger.Info($"RLogin -- User already logged in");
                var duplicateLoginMsg =
                    $"\r\n|RED||B|Duplicate user already logged in -- only 1 connection allowed per user.\r\n|RESET|"
                    .EncodeToANSIArray();
                Send(duplicateLoginMsg);
                SessionState = EnumSessionState.LoggedOff;
                return(false);
            }

            // we have 3 strings, pick out username and launch appropriately
            Username = rloginStrings.First(s => !string.IsNullOrEmpty(s));

            rloginStrings.Clear();

            _logger.Info($"Rlogin For User: {Username}");

            if (!string.IsNullOrEmpty(ModuleIdentifier))
            {
                CurrentModule = _host.GetModule(ModuleIdentifier);
                InputBuffer.WriteByte((byte)CurrentModule.MenuOptionKey[0]);
                SessionState = EnumSessionState.RloginEnteringModule;
            }
            else
            {
                SessionState = EnumSessionState.LoginRoutines;
            }

            //Send 0 byte to ACK
            Send(new byte[] { 0x0 });

            return(true);
        }