Exemple #1
0
        private bool Initialize()
        {
            // Create temporary environment file
            FileUtils.FileWriteAllText(EnvFile, Environment.GetEnvironmentVariable("COMSPEC") + " /C " + _Command + " " + _Parameters);

            // Create a hungup event for when user drops carrier
            HungUpEvent = NativeMethods.CreateEvent(IntPtr.Zero, true, false, "sbbsexec_hungup" + _ClientThread.NodeInfo.Node.ToString());
            if (HungUpEvent == IntPtr.Zero)
            {
                RMLog.Error("CreateEvent() failed to create HungUpEvent: " + Marshal.GetLastWin32Error().ToString());
                return(false);
            }

            // Create a hangup event (for when the door requests to drop DTR)
            HangUpEvent = NativeMethods.CreateEvent(IntPtr.Zero, true, false, "sbbsexec_hangup" + _ClientThread.NodeInfo.Node.ToString());
            if (HangUpEvent == IntPtr.Zero)
            {
                RMLog.Error("CreateEvent() failed to create HangUpEvent: " + Marshal.GetLastWin32Error().ToString());
                return(false);
            }

            // Create a read mail slot
            ReadSlot = NativeMethods.CreateMailslot("\\\\.\\mailslot\\sbbsexec\\rd" + _ClientThread.NodeInfo.Node.ToString(), XTRN_IO_BUF_LEN, 0, IntPtr.Zero);
            if (ReadSlot == IntPtr.Zero)
            {
                RMLog.Error("CreateMailslot() failed to create ReadSlot: " + Marshal.GetLastWin32Error().ToString());
                return(false);
            }

            return(true);
        }
Exemple #2
0
        public void Run()
        {
            try {
                // Clear the buffers and reset the screen
                _ClientThread.NodeInfo.Connection.ReadString();
                _ClientThread.ClrScr();

                // Create the node directory and drop files
                CreateNodeDirectory();

                // Determine how to run the door
                if (((_ClientThread.NodeInfo.Door.Platform == OSUtils.Platform.Linux) && OSUtils.IsUnix) || ((_ClientThread.NodeInfo.Door.Platform == OSUtils.Platform.Windows) && OSUtils.IsWindows))
                {
                    RunDoorNative(TranslateCLS(_ClientThread.NodeInfo.Door.Command), TranslateCLS(_ClientThread.NodeInfo.Door.Parameters));
                }
                else if ((_ClientThread.NodeInfo.Door.Platform == OSUtils.Platform.DOS) && OSUtils.IsWindows)
                {
                    if (ProcessUtils.Is64BitOperatingSystem)
                    {
                        if (Helpers.IsDOSBoxInstalled())
                        {
                            RunDoorDOSBox(TranslateCLS(_ClientThread.NodeInfo.Door.Command), TranslateCLS(_ClientThread.NodeInfo.Door.Parameters));
                        }
                        else
                        {
                            RMLog.Error("DOS doors are not supported on 64bit Windows (unless you install DOSBox 0.73)");
                        }
                    }
                    else
                    {
                        (new RunDoorSBBSEXEC(_ClientThread)).Run(TranslateCLS(_ClientThread.NodeInfo.Door.Command), TranslateCLS(_ClientThread.NodeInfo.Door.Parameters), _ClientThread.NodeInfo.Door.ForceQuitDelay);
                    }
                }
                else if ((_ClientThread.NodeInfo.Door.Platform == OSUtils.Platform.DOS) && OSUtils.IsUnix)
                {
                    if (Helpers.IsDOSEMUInstalled())
                    {
                        RunDoorDOSEMU(TranslateCLS(_ClientThread.NodeInfo.Door.Command), TranslateCLS(_ClientThread.NodeInfo.Door.Parameters));
                    }
                    else
                    {
                        RMLog.Error("DOS doors are not supported on Linux (unless you install DOSEMU)");
                    }
                }
                else
                {
                    RMLog.Error("Unsure how to run door on current platform");
                }
            } catch (Exception ex) {
                RMLog.Exception(ex, "Error while running door '" + _ClientThread.NodeInfo.Door.Name + "'");
            } finally {
                // Clean up
                try {
                    _ClientThread.ClrScr();
                    _ClientThread.NodeInfo.Connection.SetBlocking(true); // In case native door disabled blocking sockets
                    DeleteNodeDirectory();
                } catch { /* Ignore */ }
            }
        }
        protected override void Execute()
        {
            using (_Server = new WebSocketConnection()) {
                if (_Server.Listen(_Address, _Port))
                {
                    RaiseListeningEvent();

                    while (!_Stop)
                    {
                        try {
                            // Accept an incoming connection
                            if (_Server.CanAccept(1000)) // 1 second
                            {
                                Socket NewSocket = _Server.Accept();
                                if (NewSocket != null)
                                {
                                    lock (_ClientThreadsLock) {
                                        WebSocketClientThread ClientThread = new WebSocketClientThread(NewSocket, ++_ClientThreadCounter);
                                        ClientThread.FinishEvent += ClientThread_FinishEvent;
                                        _ClientThreads.Add(ClientThread);
                                        RMLog.Info(_ClientThreads.Count.ToString() + " active connections");
                                        ClientThread.Start();
                                    }
                                }
                            }
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "Unable to accept new websocket connection");
                        }
                    }

                    // Stop client threads
                    int ClientThreadCount = 0;
                    lock (_ClientThreadsLock) {
                        foreach (var ClientThread in _ClientThreads)
                        {
                            if (ClientThread != null)
                            {
                                ClientThread.Stop();
                            }
                        }
                        ClientThreadCount = _ClientThreads.Count;
                    }

                    // Wait for client threads
                    while (ClientThreadCount > 0)
                    {
                        lock (_ClientThreadsLock) {
                            ClientThreadCount = _ClientThreads.Count;
                        }
                        Thread.Sleep(100);
                    }
                }
                else
                {
                    RMLog.Error("WebSocket Server Thread: Unable to listen on " + _Address + ":" + _Port);
                }
            }
        }
Exemple #4
0
 public void Run(string door)
 {
     _ClientThread.NodeInfo.Door = new DoorInfo(door);
     if (_ClientThread.NodeInfo.Door.Loaded)
     {
         Run();
     }
     else
     {
         RMLog.Error("Unable to find door: '" + door + "'");
     }
 }
Exemple #5
0
 private void StopProcess()
 {
     try {
         // Terminate process if it hasn't closed yet
         if ((P != null) && !P.HasExited)
         {
             RMLog.Error("Door still running, performing a force quit");
             P.Kill();
         }
     } catch (Exception ex) {
         RMLog.Exception(ex, "Unable to perform force quit");
     }
 }
Exemple #6
0
 public static void CheckFor3rdPartySoftware()
 {
     if (OSUtils.IsWinNT)
     {
         if (ProcessUtils.Is64BitOperatingSystem)
         {
             if (!Helpers.IsDOSBoxInstalled())
             {
                 RMLog.Error("PLEASE INSTALL DOSBOX 0.73 IF YOU PLAN ON RUNNING DOS DOORS USING DOSBOX");
             }
         }
         else
         {
             if (!File.Exists(StringUtils.PathCombine(Environment.SystemDirectory, "sbbsexec.dll")))
             {
                 RMLog.Error("PLEASE COPY SBBSEXEC.DLL TO " + StringUtils.PathCombine(Environment.SystemDirectory, "sbbsexec.dll").ToUpper() + " IF YOU PLAN ON RUNNING DOS DOORS USING THE EMBEDDED SYNCHRONET FOSSIL");
             }
         }
     }
 }
Exemple #7
0
 protected override void Execute()
 {
     while (!_Stop)
     {
         using (TcpConnection Connection = new TcpConnection()) {
             if (Connection.Listen(_LocalAddress, _LocalPort))
             {
                 while (!_Stop)
                 {
                     // Accept an incoming connection
                     if (Connection.CanAccept(1000)) // 1 second
                     {
                         try {
                             TcpConnection NewConnection = Connection.AcceptTCP();
                             if (NewConnection != null)
                             {
                                 // TODOX Add check for flash socket policy request by doing a peek with a 1 second timeout or something
                                 //       If peeked character is < then peek another character to see if it's the flash request string
                                 HandleNewConnection(NewConnection);
                             }
                         } catch (Exception ex) {
                             RMLog.Exception(ex, "Error in ServerThread::Execute()");
                         }
                     }
                 }
             }
             else
             {
                 RMLog.Error($"{_ConnectionType} Server Thread unable to listen on {_LocalAddress}:{_LocalPort}.  Retry in 15 seconds.");
                 for (int i = 1; i <= 15; i++)
                 {
                     Thread.Sleep(1000);
                     if (_Stop)
                     {
                         break;
                     }
                 }
             }
         }
     }
 }
        public static void StartThreads()
        {
            if ((Config.Instance.RLoginServerPort > 0) || (Config.Instance.TelnetServerPort > 0))
            {
                RMLog.Info("Starting Server Threads");

                try {
                    _ServerThreads.Clear();

                    if (Config.Instance.RLoginServerPort > 0)
                    {
                        // Create Server Thread and add to collection
                        _ServerThreads.Add(Config.Instance.RLoginServerPort, new RLoginServerThread());
                    }

                    if (Config.Instance.TelnetServerPort > 0)
                    {
                        // Create Server Thread and add to collection
                        _ServerThreads.Add(Config.Instance.TelnetServerPort, new TelnetServerThread());
                    }

                    if (Config.Instance.WebSocketServerPort > 0)
                    {
                        // Create Server Thread and add to collection
                        _ServerThreads.Add(Config.Instance.WebSocketServerPort, new WebSocketServerThread());
                    }

                    // Now actually start the server threads
                    foreach (var KVP in _ServerThreads)
                    {
                        KVP.Value.Start();
                    }
                } catch (Exception ex) {
                    RMLog.Exception(ex, "Error in ServerThreadManager::StartThreads()");
                }
            }
            else
            {
                RMLog.Error("Must specify a port for RLogin and/or Telnet servers");
            }
        }
 void ClientThread_FinishEvent(object sender, EventArgs e)
 {
     if (sender is WebSocketClientThread)
     {
         lock (_ClientThreadsLock) {
             if (_ClientThreads.Contains((WebSocketClientThread)sender))
             {
                 _ClientThreads.Remove((WebSocketClientThread)sender);
                 RMLog.Info(_ClientThreads.Count.ToString() + " active connections");
             }
             else
             {
                 RMLog.Error("ClientThread_FinishEvent did not find sender in _ClientThreads (sender=" + sender.ToString() + ")");
             }
         }
     }
     else
     {
         RMLog.Error("ClientThread_FinishEvent's sender is not a WebSocketClientThread (sender=" + sender.ToString() + ")");
     }
 }
Exemple #10
0
        private bool StartProcess()
        {
            // Start the process
            string           FileName  = StringUtils.PathCombine(ProcessUtils.StartupPath, "DOSXTRN.EXE");
            string           Arguments = StringUtils.ExtractShortPathName(EnvFile) + " NT " + _ClientThread.NodeInfo.Node.ToString() + " " + SBBSEXEC_MODE_FOSSIL.ToString() + " " + LoopsBeforeYield.ToString();
            ProcessStartInfo PSI       = new ProcessStartInfo(FileName, Arguments)
            {
                WindowStyle      = _ClientThread.NodeInfo.Door.WindowStyle,
                WorkingDirectory = ProcessUtils.StartupPath,
            };

            P = RMProcess.Start(PSI);

            if (P == null)
            {
                RMLog.Error("Error launching " + FileName + " " + Arguments);
                return(false);
            }
            else
            {
                return(true);
            }
        }
        protected override void Execute()
        {
            try {
                // Handle non-proxy connections
                using (WebSocketConnection UserConnection = new WebSocketConnection(true, Config.Default.Certificate)) {
                    if (UserConnection.Open(_Socket))
                    {
                        _RemoteIP = UserConnection.GetRemoteIP();

                        RMLog.Debug("{" + _ConnectionId.ToString() + "} Opened connection from " + UserConnection.GetRemoteIP() + ":" + UserConnection.GetRemotePort());
                        if (UserConnection.Header["Path"] == "/ping")
                        {
                            // Handle ping requests (from proxy.ftelnet.ca most likely)
                            string Ping = UserConnection.ReadLn(1000);
                            if (UserConnection.ReadTimedOut)
                            {
                                RMLog.Debug("Answering a /ping (no time received) from " + UserConnection.GetRemoteIP() + ":" + UserConnection.GetRemotePort());
                            }
                            else
                            {
                                RMLog.Debug("Answering a /ping (" + Ping + ") from " + UserConnection.GetRemoteIP() + ":" + UserConnection.GetRemotePort());
                                UserConnection.Write(Ping);
                            }
                            return;
                        }
                    }
                    else
                    {
                        if (UserConnection.FlashPolicyFileRequest)
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Answered flash policy file request from " + UserConnection.GetRemoteIP() + ":" + UserConnection.GetRemotePort().ToString());
                        }
                        else
                        {
                            RMLog.Debug("{" + _ConnectionId.ToString() + "} Invalid WebSocket connection from " + UserConnection.GetRemoteIP() + ":" + UserConnection.GetRemotePort().ToString());
                        }
                        return;
                    }

                    // If we get here it's a proxy connection, so handle it
                    RMLog.Info("{" + _ConnectionId.ToString() + "} Connection accepted from " + UserConnection.GetRemoteIP() + ":" + UserConnection.GetRemotePort());

                    string MessageText = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\r\n",
                                                       DateTime.Now.ToString(),
                                                       UserConnection.GetRemoteIP(),
                                                       UserConnection.GetRemotePort(),
                                                       UserConnection.Header["Path"],
                                                       UserConnection.Protocol,
                                                       UserConnection.SubProtocol);
                    FileUtils.FileAppendAllText(Path.Combine(ProcessUtils.StartupPath, "fTelnetProxy-Connections.log"), MessageText, Encoding.ASCII);

                    // Defaults for redirect location
                    _Hostname = Config.Default.TargetHostname;
                    _Port     = Config.Default.TargetPort;

                    // Check if user is requesting a custom target
                    if (UserConnection.Header["Path"] != "/")
                    {
                        bool CanRelay = false;

                        // Extract the requested host and port
                        string[] HostAndPort = UserConnection.Header["Path"].Split('/');
                        if ((HostAndPort.Length == 3) && (int.TryParse(HostAndPort[2], out _Port)))
                        {
                            _Hostname = HostAndPort[1];
                            if (Config.Default.TargetHostname.ToLower().Trim() == _Hostname.ToLower().Trim())
                            {
                                // User is requesting the target defined by the proxy admin, so check if it's to an allowed port
                                CanRelay = ((_Port > 0) && (_Port == Config.Default.TargetPort) || (_Port == Config.Default.RLoginPort));
                            }
                            else if (!string.IsNullOrEmpty(Config.Default.RelayFilename))
                            {
                                // proxy admin has relaying enabled, so check against the relay.cfg file
                                try {
                                    // Read relay file
                                    if (File.Exists(Config.Default.RelayFilename))
                                    {
                                        string[] AllowedHosts = File.ReadAllLines(Config.Default.RelayFilename);
                                        if (AllowedHosts.Length > 0)
                                        {
                                            // Check for a whitelisted port
                                            string[] AllowedPorts = AllowedHosts[0].Split(',');
                                            foreach (string AllowedPort in AllowedPorts)
                                            {
                                                if (AllowedPort == _Port.ToString())
                                                {
                                                    CanRelay = true;
                                                    break;
                                                }
                                            }

                                            // Not a whitelisted port, check for a whitelisted host
                                            if (!CanRelay)
                                            {
                                                string RequestedHostPort = _Hostname.ToLower() + ":" + _Port.ToString();
                                                foreach (string AllowedHost in AllowedHosts)
                                                {
                                                    if (AllowedHost.Trim().ToLower() == RequestedHostPort)
                                                    {
                                                        CanRelay = true;
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            RMLog.Error("{" + _ConnectionId.ToString() + "} Relay file is empty: '" + Config.Default.RelayFilename + "'");
                                        }
                                    }
                                    else
                                    {
                                        RMLog.Error("{" + _ConnectionId.ToString() + "} Relay file does not exist: '" + Config.Default.RelayFilename + "'");
                                    }
                                } catch (Exception ex) {
                                    RMLog.Exception(ex, "{" + _ConnectionId.ToString() + "} Error reading relay file: '" + Config.Default.RelayFilename + "'");
                                }
                            }
                        }

                        if (!CanRelay)
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Rejecting request for " + _Hostname + ":" + _Port.ToString());
                            UserConnection.WriteLn("Sorry, for security reasons this proxy won't connect to " + _Hostname + ":" + _Port.ToString());
                            UserConnection.WriteLn("unless you contact me via the contact form on www.fTelnet.ca.  Just let me");
                            UserConnection.WriteLn("know the hostname and port you're trying to connect to, and I'll add it to");
                            UserConnection.WriteLn("the whitelist for you.");
                            Thread.Sleep(2500);
                            return;
                        }
                    }

                    // Try to connect to the desired Host and Port
                    UserConnection.Write(Ansi.ClrScr() + "Connecting to " + _Hostname + ":" + _Port.ToString() + "...");
                    using (TcpConnection ServerConnection = new TcpConnection()) {
                        if (ServerConnection.Connect(_Hostname, _Port))
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Connected to " + _Hostname + ":" + _Port.ToString());
                            UserConnection.WriteLn("connected!");

                            // Repeatedly move data around until a connection is closed (or a stop is requested)
                            bool DoSleep = true;
                            while (!_Stop && UserConnection.Connected && ServerConnection.Connected)
                            {
                                DoSleep = true;

                                if (UserConnection.CanRead())
                                {
                                    ServerConnection.WriteBytes(UserConnection.ReadBytes());
                                    _DateLastTX = DateTime.Now;
                                    DoSleep     = false;
                                }

                                if (ServerConnection.CanRead())
                                {
                                    UserConnection.WriteBytes(ServerConnection.ReadBytes(1024)); // 1k at a time to allow non-stop screens to be aborted by user input
                                    _DateLastRX = DateTime.Now;
                                    DoSleep     = false;
                                }

                                if (DoSleep)
                                {
                                    Thread.Sleep(1);
                                }

                                // Check if we should abort due to idle times
                                // TODOX Allow to be customized
                                if (SecondsSinceLastRX > 600)
                                {
                                    // 10 minutes of no server activity
                                    RMLog.Info("{" + _ConnectionId.ToString() + "} Disconnecting after 10 minutes of no activity from server");
                                    UserConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nDisconnecting after 10 minutes of no activity from server...");
                                    Thread.Sleep(2500);
                                    break;
                                }
                                else if (SecondsSinceLastTX > 600)
                                {
                                    // 10 minutes of no user activity
                                    RMLog.Info("{" + _ConnectionId.ToString() + "} Disconnecting after 10 minutes of no activity from user");
                                    UserConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nDisconnecting after 10 minutes of no activity from user...");
                                    Thread.Sleep(2500);
                                    break;
                                }
                                else if (SecondsSinceConnecting > 21600)
                                {
                                    // 6 hours since connecting
                                    RMLog.Info("{" + _ConnectionId.ToString() + "} Disconnecting after 6 hours");
                                    UserConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nDisconnecting after 6 hours...");
                                    Thread.Sleep(2500);
                                    break;
                                }
                            }

                            // Check why we exited the loop
                            if (_Stop)
                            {
                                RMLog.Info("{" + _ConnectionId.ToString() + "} Stop requested");
                                UserConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nProxy server shutting down...");
                                Thread.Sleep(2500);
                            }
                            else if (!UserConnection.Connected)
                            {
                                RMLog.Info("{" + _ConnectionId.ToString() + "} Client closed connection");
                            }
                            else if (!ServerConnection.Connected)
                            {
                                RMLog.Info("{" + _ConnectionId.ToString() + "} Server closed connection");
                                UserConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nServer closed connection...");
                                Thread.Sleep(2500);
                            }
                        }
                        else
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Unable to connect to " + _Hostname + ":" + _Port.ToString());
                            UserConnection.WriteLn("unable to connect!");
                            Thread.Sleep(2500);
                        }
                    }

                    // Display info about the connection we're closing
                    DisplayConnectionInformation();
                }
            } catch (Exception ex) {
                RMLog.Exception(ex, "{" + _ConnectionId.ToString() + "} Exception in client thread");
            }
        }
Exemple #12
0
        protected override void Execute()
        {
            try {
                // Handle non-proxy connections
                using (WebSocketConnection NewConnection = new WebSocketConnection(true, Config.Default.Certificate)) {
                    if (NewConnection.Open(_Socket))
                    {
                        RMLog.Debug("{" + _ConnectionId.ToString() + "} Opened connection from " + NewConnection.GetRemoteIP() + ":" + NewConnection.GetRemotePort());
                        if (NewConnection.Header["Path"] == "/ping")
                        {
                            // Handle ping requests (from proxy.ftelnet.ca most likely)
                            string Ping = NewConnection.ReadLn(1000);
                            if (NewConnection.ReadTimedOut)
                            {
                                RMLog.Debug("Answering a /ping (no time received) from " + NewConnection.GetRemoteIP() + ":" + NewConnection.GetRemotePort());
                            }
                            else
                            {
                                RMLog.Debug("Answering a /ping (" + Ping + ") from " + NewConnection.GetRemoteIP() + ":" + NewConnection.GetRemotePort());
                                NewConnection.Write(Ping);
                            }
                            return;
                        }
                    }
                    else
                    {
                        if (NewConnection.FlashPolicyFileRequest)
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Answered flash policy file request from " + NewConnection.GetRemoteIP() + ":" + NewConnection.GetRemotePort().ToString());
                        }
                        else
                        {
                            RMLog.Debug("{" + _ConnectionId.ToString() + "} Invalid WebSocket connection from " + NewConnection.GetRemoteIP() + ":" + NewConnection.GetRemotePort().ToString());
                        }
                        return;
                    }

                    // If we get here it's a proxy connection, so handle it
                    RMLog.Info("{" + _ConnectionId.ToString() + "} Connection accepted from " + NewConnection.GetRemoteIP() + ":" + NewConnection.GetRemotePort());

                    string MessageText = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\r\n",
                                                       DateTime.Now.ToString(),
                                                       NewConnection.GetRemoteIP(),
                                                       NewConnection.GetRemotePort(),
                                                       NewConnection.Header["Path"],
                                                       NewConnection.Protocol,
                                                       NewConnection.SubProtocol);
                    FileUtils.FileAppendAllText(Path.Combine(ProcessUtils.StartupPath, "fTelnetProxy-Connections.log"), MessageText, Encoding.ASCII);

                    // Defaults for redirect location
                    string Hostname = Config.Default.TargetHostname;
                    int    Port     = Config.Default.TargetPort;

                    // Check if user is requesting a custom target
                    if (NewConnection.Header["Path"] != "/")
                    {
                        bool CanRelay = false;

                        // Extract the requested host and port
                        string[] HostAndPort = NewConnection.Header["Path"].Split('/');
                        if ((HostAndPort.Length == 3) && (int.TryParse(HostAndPort[2], out Port)))
                        {
                            Hostname = HostAndPort[1];
                            if (Config.Default.TargetHostname.ToLower().Trim() == Hostname.ToLower().Trim())
                            {
                                // User is requesting the target defined by the proxy admin, so check if it's to an allowed port
                                CanRelay = ((Port > 0) && (Port == Config.Default.TargetPort) || (Port == Config.Default.RLoginPort));
                            }
                            else if (!string.IsNullOrEmpty(Config.Default.RelayFilename))
                            {
                                // proxy admin has relaying enabled, so check against the relay.cfg file
                                try {
                                    // Read relay file
                                    if (File.Exists(Config.Default.RelayFilename))
                                    {
                                        string[] AllowedHosts = File.ReadAllLines(Config.Default.RelayFilename);
                                        if (AllowedHosts.Length > 0)
                                        {
                                            // Check for a whitelisted port
                                            string[] AllowedPorts = AllowedHosts[0].Split(',');
                                            foreach (string AllowedPort in AllowedPorts)
                                            {
                                                if (AllowedPort == Port.ToString())
                                                {
                                                    CanRelay = true;
                                                    break;
                                                }
                                            }

                                            // Not a whitelisted port, check for a whitelisted host
                                            if (!CanRelay)
                                            {
                                                string RequestedHostPort = Hostname.ToLower() + ":" + Port.ToString();
                                                foreach (string AllowedHost in AllowedHosts)
                                                {
                                                    if (AllowedHost.Trim().ToLower() == RequestedHostPort)
                                                    {
                                                        CanRelay = true;
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            RMLog.Error("{" + _ConnectionId.ToString() + "} Relay file is empty: '" + Config.Default.RelayFilename + "'");
                                        }
                                    }
                                    else
                                    {
                                        RMLog.Error("{" + _ConnectionId.ToString() + "} Relay file does not exist: '" + Config.Default.RelayFilename + "'");
                                    }
                                } catch (Exception ex) {
                                    RMLog.Exception(ex, "{" + _ConnectionId.ToString() + "} Error reading relay file: '" + Config.Default.RelayFilename + "'");
                                }
                            }
                        }

                        if (!CanRelay)
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Rejecting request for " + Hostname + ":" + Port.ToString());
                            NewConnection.WriteLn("Sorry, for security reasons this proxy won't connect to " + Hostname + ":" + Port.ToString());
                            Thread.Sleep(2500);
                            return;
                        }
                    }

                    // Try to connect to the desired Host and Port
                    NewConnection.Write(Ansi.ClrScr() + "Connecting to " + Hostname + ":" + Port.ToString() + "...");
                    using (TcpConnection _TcpConnection = new TcpConnection()) {
                        if (_TcpConnection.Connect(Hostname, Port))
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Connected to " + Hostname + ":" + Port.ToString());
                            NewConnection.WriteLn("connected!");

                            // Repeatedly move data around until a connection is closed (or a stop is requested)
                            bool DoSleep = true;
                            while (!_Stop && NewConnection.Connected && _TcpConnection.Connected)
                            {
                                DoSleep = true;

                                if (NewConnection.CanRead())
                                {
                                    _TcpConnection.WriteBytes(NewConnection.ReadBytes());
                                    DoSleep = false;
                                }

                                if (_TcpConnection.CanRead())
                                {
                                    NewConnection.WriteBytes(_TcpConnection.ReadBytes());
                                    DoSleep = false;
                                }

                                if (DoSleep)
                                {
                                    Thread.Sleep(1);
                                }
                            }

                            // Check why we exited the loop
                            if (_Stop)
                            {
                                RMLog.Info("{" + _ConnectionId.ToString() + "} Stop requested");
                                NewConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nProxy server shutting down...");
                                Thread.Sleep(2500);
                            }
                            else if (!NewConnection.Connected)
                            {
                                RMLog.Info("{" + _ConnectionId.ToString() + "} Client closed connection");
                            }
                            else if (!_TcpConnection.Connected)
                            {
                                RMLog.Info("{" + _ConnectionId.ToString() + "} Server closed connection");
                                NewConnection.Write(Ansi.GotoXY(1, 1) + Ansi.CursorDown(255) + "\r\nServer closed connection...");
                                Thread.Sleep(2500);
                            }
                        }
                        else
                        {
                            RMLog.Info("{" + _ConnectionId.ToString() + "} Unable to connect to " + Hostname + ":" + Port.ToString());
                            NewConnection.WriteLn("unable to connect!");
                            Thread.Sleep(2500);
                        }
                    }
                }
            } catch (Exception ex) {
                RMLog.Exception(ex, "{" + _ConnectionId.ToString() + "} Exception in client thread");
            }
        }
Exemple #13
0
        // TODOY Consolidate with ParseEnvironmentVariables
        private void ParseCommandLineArgs()
        {
            string[] Args = Environment.GetCommandLineArgs();
            if (Args.Length > 1)
            {
                RMLog.Info("Overriding with settings from command-line");

                for (int i = 1; i < Args.Length; i++)
                {
                    string Arg = Args[i].TrimStart('/').TrimStart('-');
                    switch (Arg)
                    {
                    case "c":
                    case "cert":
                        i += 1;

                        // If file doesn't exist, and it's relative, convert to absolute
                        if (!File.Exists(Args[i]) && !Path.IsPathRooted(Args[i]))
                        {
                            Args[i] = StringUtils.PathCombine(ProcessUtils.StartupPath, Args[i]);
                        }

                        if (File.Exists(Args[i]))
                        {
                            Config.Default.CertificateFilename = Args[i];
                            RMLog.Info("-Cert file......" + Config.Default.CertificateFilename);
                        }
                        else
                        {
                            RMLog.Error("-Cert file not found: '" + Args[i] + "'");
                        }
                        break;

                    case "?":
                    case "h":
                    case "help":
                        ShowHelp();
                        return;

                    case "l":
                    case "loglevel":
                        i += 1;
                        try {
                            RMLog.Level = (LogLevel)Enum.Parse(typeof(LogLevel), Args[i]);
                            RMLog.Info("-Log level......" + RMLog.Level.ToString());
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "-Invalid log level: '" + Args[i] + "'");
                        }
                        break;

                    case "p":
                    case "port":
                        i += 1;
                        try {
                            Config.Default.ListenPort = Convert.ToInt16(Args[i]);
                            RMLog.Info("-Listen port...." + Config.Default.ListenPort.ToString());
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "-Invalid port: '" + Args[i] + "'");
                        }
                        break;

                    case "pw":
                    case "password":
                        i += 1;
                        Config.Default.CertificatePassword = Args[i];
                        RMLog.Info("-Cert password..yes (hidden)");
                        break;

                    case "r":
                    case "relay":
                        i += 1;

                        // If file doesn't exist, and it's relative, convert to absolute
                        if (!File.Exists(Args[i]) && !Path.IsPathRooted(Args[i]))
                        {
                            Args[i] = StringUtils.PathCombine(ProcessUtils.StartupPath, Args[i]);
                        }

                        if (File.Exists(Args[i]))
                        {
                            Config.Default.RelayFilename = Args[i];
                            RMLog.Info("-Relay file....." + Config.Default.RelayFilename);
                        }
                        else
                        {
                            Config.Default.RelayFilename = "";
                            RMLog.Error("-Relay file not found: '" + Args[i] + "'");
                        }
                        break;

                    case "rp":
                    case "rlogin-port":
                        i += 1;
                        try {
                            Config.Default.RLoginPort = Convert.ToInt16(Args[i]);
                            if (Config.Default.RLoginPort > 0)
                            {
                                // TODOX If -rp is specified before -t, then this will display the wrong hostname
                                RMLog.Info("-RLogin target.." + Config.Default.TargetHostname + ":" + Config.Default.RLoginPort.ToString());
                            }
                            else
                            {
                                RMLog.Info("-RLogin target..DISABLED");
                            }
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "-Invalid port: '" + Args[i] + "'");
                        }
                        break;

                    case "t":
                    case "target":
                        i += 1;
                        string TargetHostname = Config.Default.TargetHostname;
                        int    TargetPort     = Config.Default.TargetPort;
                        WebUtils.ParseHostPort(Args[i], ref TargetHostname, ref TargetPort);
                        Config.Default.TargetHostname = TargetHostname;
                        Config.Default.TargetPort     = TargetPort;
                        if (Config.Default.TargetPort > 0)
                        {
                            RMLog.Info("-Telnet target.." + Config.Default.TargetHostname + ":" + Config.Default.TargetPort.ToString());
                        }
                        else
                        {
                            RMLog.Info("-Telnet target..DISABLED");
                        }
                        break;

                    default:
                        RMLog.Error("-Unknown parameter: '" + Args[i] + "'");
                        break;
                    }
                }
            }
        }
Exemple #14
0
        // TODOY Consolidate with ParseCommandLine
        private void ParseEnvironmentVariables()
        {
            var EnvironmentVariables = Environment.GetEnvironmentVariables().Cast <DictionaryEntry>().Where(x => x.Key.ToString().ToLower().StartsWith("ftelnet_")).ToArray();

            if (EnvironmentVariables.Length > 0)
            {
                RMLog.Info("Overriding with settings from environment variables");

                for (int i = 0; i < EnvironmentVariables.Length; i++)
                {
                    string Arg   = EnvironmentVariables[i].Key.ToString().Substring(8).ToLower().Replace('_', '-'); // Substring off the leading ftelnet_ and replace _ with -
                    string Value = EnvironmentVariables[i].Value.ToString();

                    switch (Arg)
                    {
                    case "c":
                    case "cert":
                        // If file doesn't exist, and it's relative, convert to absolute
                        if (!File.Exists(Value) && !Path.IsPathRooted(Value))
                        {
                            Value = StringUtils.PathCombine(ProcessUtils.StartupPath, Value);
                        }

                        if (File.Exists(Value))
                        {
                            Config.Default.CertificateFilename = Value;
                            RMLog.Info("-Cert file......" + Config.Default.CertificateFilename);
                        }
                        else
                        {
                            RMLog.Error("-Cert file not found: '" + Value + "'");
                        }
                        break;

                    case "l":
                    case "loglevel":
                        try {
                            RMLog.Level = (LogLevel)Enum.Parse(typeof(LogLevel), Value);
                            RMLog.Info("-Log level......" + RMLog.Level.ToString());
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "-Invalid log level: '" + Value + "'");
                        }
                        break;

                    case "p":
                    case "port":
                        try {
                            Config.Default.ListenPort = Convert.ToInt16(Value);
                            RMLog.Info("-Listen port...." + Config.Default.ListenPort.ToString());
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "-Invalid port: '" + Value + "'");
                        }
                        break;

                    case "pw":
                    case "password":
                        Config.Default.CertificatePassword = Value;
                        RMLog.Info("-Cert password..yes (hidden)");
                        break;

                    case "r":
                    case "relay":
                        // If file doesn't exist, and it's relative, convert to absolute
                        if (!File.Exists(Value) && !Path.IsPathRooted(Value))
                        {
                            Value = StringUtils.PathCombine(ProcessUtils.StartupPath, Value);
                        }

                        if (File.Exists(Value))
                        {
                            Config.Default.RelayFilename = Value;
                            RMLog.Info("-Relay file....." + Config.Default.RelayFilename);
                        }
                        else
                        {
                            Config.Default.RelayFilename = "";
                            RMLog.Error("-Relay file not found: '" + Value + "'");
                        }
                        break;

                    case "rp":
                    case "rlogin-port":
                        try {
                            Config.Default.RLoginPort = Convert.ToInt16(Value);
                            if (Config.Default.RLoginPort > 0)
                            {
                                // TODOX If -rp is specified before -t, then this will display the wrong hostname
                                RMLog.Info("-RLogin target.." + Config.Default.TargetHostname + ":" + Config.Default.RLoginPort.ToString());
                            }
                            else
                            {
                                RMLog.Info("-RLogin target..DISABLED");
                            }
                        } catch (Exception ex) {
                            RMLog.Exception(ex, "-Invalid port: '" + Value + "'");
                        }
                        break;

                    case "t":
                    case "target":
                        string TargetHostname = Config.Default.TargetHostname;
                        int    TargetPort     = Config.Default.TargetPort;
                        WebUtils.ParseHostPort(Value, ref TargetHostname, ref TargetPort);
                        Config.Default.TargetHostname = TargetHostname;
                        Config.Default.TargetPort     = TargetPort;
                        if (Config.Default.TargetPort > 0)
                        {
                            RMLog.Info("-Telnet target.." + Config.Default.TargetHostname + ":" + Config.Default.TargetPort.ToString());
                        }
                        else
                        {
                            RMLog.Info("-Telnet target..DISABLED");
                        }
                        break;

                    default:
                        RMLog.Error("-Unknown parameter: '" + Arg + "'");
                        break;
                    }
                }
            }
        }
Exemple #15
0
        public new void Load()
        {
            // Try to load, and save a new file if load failed
            if (!base.Load())
            {
                base.Save();
            }

            RMLog.Level = LogLevel;

            // Output the settings being used
            RMLog.Info("Using settings from " + base.FileName);
            RMLog.Info("-Listen port...." + ListenPort.ToString());
            if (TargetPort > 0)
            {
                RMLog.Info("-Telnet target.." + TargetHostname + ":" + TargetPort.ToString());
            }
            else
            {
                RMLog.Info("-Telnet target..DISABLED");
            }
            if (RLoginPort > 0)
            {
                RMLog.Info("-RLogin target.." + TargetHostname + ":" + RLoginPort.ToString());
            }
            else
            {
                RMLog.Info("-RLogin target..DISABLED");
            }
            RMLog.Info("-Log level......" + LogLevel.ToString());
            if (CertificateFilename != "")
            {
                // If file doesn't exist, and it's relative, convert to absolute
                if (!File.Exists(CertificateFilename) && !Path.IsPathRooted(CertificateFilename))
                {
                    CertificateFilename = StringUtils.PathCombine(ProcessUtils.StartupPath, CertificateFilename);
                }

                if (File.Exists(CertificateFilename))
                {
                    RMLog.Info("-Cert file......" + CertificateFilename);
                    if (CertificatePassword == "")
                    {
                        RMLog.Info("-Cert password..none");
                    }
                    else
                    {
                        RMLog.Info("-Cert password..yes (hidden)");
                    }
                }
                else
                {
                    RMLog.Error("-Cert file not found: '" + CertificateFilename + "'");
                    CertificateFilename = "";
                }
            }
            if (RelayFilename != "")
            {
                // If file doesn't exist, and it's relative, convert to absolute
                if (!File.Exists(RelayFilename) && !Path.IsPathRooted(RelayFilename))
                {
                    RelayFilename = StringUtils.PathCombine(ProcessUtils.StartupPath, RelayFilename);
                }

                if (File.Exists(RelayFilename))
                {
                    RMLog.Info("-Relay file....." + RelayFilename);
                }
                else
                {
                    RMLog.Error("-Relay file not found: '" + RelayFilename + "'");
                    RelayFilename = "";
                }
            }
        }
Exemple #16
0
        public new void Load()
        {
            // Try to load, and save a new file if load failed
            if (!base.Load())
            {
                base.Save();
            }

            RMLog.Level = LogLevel;

            // Output the settings being used
            RMLog.Info("Using settings from " + base.FileName);
            RMLog.Info("-Listen port: " + ListenPort.ToString());
            if (TargetPort > 0)
            {
                RMLog.Info("-Telnet target: " + TargetHostname + ":" + TargetPort.ToString());
            }
            else
            {
                RMLog.Info("-Telnet target: DISABLED");
            }
            if (RLoginPort > 0)
            {
                RMLog.Info("-RLogin target: " + TargetHostname + ":" + RLoginPort.ToString());
            }
            else
            {
                RMLog.Info("-RLogin target: DISABLED");
            }
            RMLog.Info("-Log level: " + LogLevel.ToString());
            if (!string.IsNullOrWhiteSpace(CertificateFilename))
            {
                // If file doesn't exist, and it's relative, convert to absolute
                if (!File.Exists(CertificateFilename) && !Path.IsPathRooted(CertificateFilename))
                {
                    CertificateFilename = StringUtils.PathCombine(ProcessUtils.StartupPath, CertificateFilename);
                }

                if (File.Exists(CertificateFilename))
                {
                    RMLog.Info("-Cert file: " + CertificateFilename);
                    if (string.IsNullOrWhiteSpace(CertificatePassword))
                    {
                        RMLog.Info("-Cert password: none");
                    }
                    else
                    {
                        RMLog.Info("-Cert password: yes (hidden)");
                    }
                }
                else
                {
                    RMLog.Error("-Cert file not found: '" + CertificateFilename + "'");
                    CertificateFilename = "";
                }
            }
            if (!string.IsNullOrWhiteSpace(User) && OSUtils.IsUnix)
            {
                RMLog.Info($"-Run as user: '******'");
            }
            if (!string.IsNullOrWhiteSpace(RelayFilename))
            {
                // If file doesn't exist, and it's relative, convert to absolute
                if (!File.Exists(RelayFilename) && !Path.IsPathRooted(RelayFilename))
                {
                    RelayFilename = StringUtils.PathCombine(ProcessUtils.StartupPath, RelayFilename);
                }

                if (File.Exists(RelayFilename))
                {
                    RMLog.Info("-Relay file: " + RelayFilename);
                }
                else
                {
                    RMLog.Error("-Relay file not found: '" + RelayFilename + "'");
                    RelayFilename = "";
                }
            }
            if (!string.IsNullOrWhiteSpace(RelayDeniedFilename))
            {
                // If file doesn't exist, and it's relative, convert to absolute
                if (!File.Exists(RelayDeniedFilename) && !Path.IsPathRooted(RelayDeniedFilename))
                {
                    RelayDeniedFilename = StringUtils.PathCombine(ProcessUtils.StartupPath, RelayDeniedFilename);
                }

                if (File.Exists(RelayDeniedFilename))
                {
                    RMLog.Info("-Relay denied file: " + RelayDeniedFilename);
                }
                else
                {
                    RMLog.Error("-Relay denied file not found: '" + RelayDeniedFilename + "'");
                    RelayDeniedFilename = "";
                }
            }
            if (MaxIdleTimeInMinutes > 0)
            {
                RMLog.Info($"-Max idle time before disconnecting: {MaxIdleTimeInMinutes} minutes");
            }
            else
            {
                RMLog.Info("-Max idle time before disconnecting: DISABLED");
            }
            if (MaxSessionLengthInHours > 0)
            {
                RMLog.Info($"-Max session length before disconnecting: {MaxSessionLengthInHours} hours");
            }
            else
            {
                RMLog.Info("-Max session length before disconnecting: DISABLED");
            }
        }
Exemple #17
0
        private unsafe bool TransmitFromUserToDoor(out bool error)
        {
            if (_ClientThread.NodeInfo.Connection.CanRead())
            {
                // If our writeslot doesnt exist yet, create it
                if (WriteSlot == IntPtr.Zero)
                {
                    // Create A Write Mail Slot
                    WriteSlot = NativeMethods.CreateFile("\\\\.\\mailslot\\sbbsexec\\wr" + _ClientThread.NodeInfo.Node.ToString(), NativeMethods.FileAccess.GenericWrite, NativeMethods.FileShare.Read, IntPtr.Zero, NativeMethods.CreationDisposition.OpenExisting, NativeMethods.CreateFileAttributes.Normal, IntPtr.Zero);
                    int LastWin32Error = Marshal.GetLastWin32Error();
                    if (WriteSlot == IntPtr.Zero)
                    {
                        RMLog.Error("CreateFile() failed to create WriteSlot: " + LastWin32Error.ToString());
                        error = true;
                        return(false);
                    }
                    else if (WriteSlot.ToInt32() == -1)
                    {
                        if (LastWin32Error == 2)
                        {
                            // ERROR_FILE_NOT_FOUND - User must have hit a key really fast to trigger this!
                            RMLog.Warning("CreateFile() failed to find WriteSlot: \\\\.\\mailslot\\sbbsexec\\wr" + _ClientThread.NodeInfo.Node.ToString());
                            WriteSlot = IntPtr.Zero;
                            Thread.Sleep(100);
                        }
                        else
                        {
                            RMLog.Error("CreateFile() failed to create WriteSlot: " + LastWin32Error.ToString());
                            error = true;
                            return(false);
                        }
                    }
                }

                // Write the text to the program
                if (WriteSlot != IntPtr.Zero)
                {
                    byte[] BufBytes       = _ClientThread.NodeInfo.Connection.PeekBytes();
                    bool   Result         = NativeMethods.WriteFile(WriteSlot, BufBytes, (uint)BufBytes.Length, out uint BytesWritten, null);
                    int    LastWin32Error = Marshal.GetLastWin32Error();
                    if (Result)
                    {
                        _ClientThread.NodeInfo.Connection.ReadBytes((int)BytesWritten);
                        error = false;
                        return(true);
                    }
                    else
                    {
                        RMLog.Error("Error calling WriteFile(): " + LastWin32Error.ToString());
                        error = true;
                        return(false);
                    }
                }
                else
                {
                    error = false;
                    return(false);
                }
            }
            else
            {
                error = false;
                return(false);
            }
        }