Inheritance: Smuxi.Engine.PermanentRemoteObject
Esempio n. 1
0
        public static void Init()
        {
            if (_IsInitialized) {
                return;
            }
            _IsInitialized = true;

            var asm = Assembly.GetEntryAssembly();
            if (asm == null) {
                asm = Assembly.GetAssembly(typeof(Engine));
            }
            var asm_name = asm.GetName(false);
            _Version = asm_name.Version;
            _VersionNumber = asm_name.Version.ToString();

            var distVersion = Defines.DistVersion;
            if (!String.IsNullOrEmpty(distVersion)) {
                distVersion = String.Format(" ({0})", distVersion);
            }
            _VersionString = String.Format(
                "{0} {1}{2} - running on {3} {4}",
                Path.GetFileNameWithoutExtension(asm_name.Name),
                _Version,
                distVersion,
                Platform.OperatingSystem,
                Platform.Architecture
            );

            _Config = new Config();
            _Config.Load();
            _Config.Save();

            string location = Assembly.GetExecutingAssembly().Location;
            _ProtocolManagerFactory = new ProtocolManagerFactory();
            _ProtocolManagerFactory.LoadAllProtocolManagers(Path.GetDirectoryName(location));

            _SessionManager = new SessionManager(_Config, _ProtocolManagerFactory);
        }
Esempio n. 2
0
        public void Connect(string engine)
        {
            Trace.Call(engine);

            if (engine == null) {
                throw new ArgumentNullException("engine");
            }
            if (engine.Length == 0) {
                throw new ArgumentException(_("Engine must not be empty."), "engine");
            }

            bool engineFound = false;
            foreach (var entry in (string[]) f_FrontendConfig["Engines/Engines"]) {
                if (entry == engine) {
                    engineFound = true;
                    break;
                }
            }
            if (!engineFound) {
                throw new ArgumentException(_("Engine does not exist."), "engine");
            }

            f_Engine = engine;
            string username = (string) f_FrontendConfig["Engines/"+engine+"/Username"];
            string password = (string) f_FrontendConfig["Engines/"+engine+"/Password"];
            string hostname = (string) f_FrontendConfig["Engines/"+engine+"/Hostname"];
            string bindAddress = (string) f_FrontendConfig["Engines/"+engine+"/BindAddress"];
            int port = (int) f_FrontendConfig["Engines/"+engine+"/Port"];
            //string formatter = (string) _FrontendConfig["Engines/"+engine+"/Formatter"];
            string channel = (string) f_FrontendConfig["Engines/"+engine+"/Channel"];

            // SSH tunnel support
            bool useSshTunnel = false;
            if (f_FrontendConfig["Engines/"+engine+"/UseSshTunnel"] != null) {
                useSshTunnel = (bool) f_FrontendConfig["Engines/"+engine+"/UseSshTunnel"];
            }
            string sshProgram = (string) f_FrontendConfig["Engines/"+engine+"/SshProgram"];
            string sshParameters = (string) f_FrontendConfig["Engines/"+engine+"/SshParameters"];
            string sshHostname = (string) f_FrontendConfig["Engines/"+engine+"/SshHostname"];
            int sshPort = -1;
            if (f_FrontendConfig["Engines/"+engine+"/SshPort"] != null) {
                sshPort = (int) f_FrontendConfig["Engines/"+engine+"/SshPort"];
            }
            string sshUsername = (string) f_FrontendConfig["Engines/"+engine+"/SshUsername"];
            string sshPassword = (string) f_FrontendConfig["Engines/"+engine+"/SshPassword"];
            var sshKeyfile = (string) f_FrontendConfig["Engines/"+engine+"/SshKeyfile"];

            // OPT: always use SSH compression (both openssh and plink support it)
            // this reduces the .NET remoting traffic by about 75%
            if (String.IsNullOrEmpty(sshParameters) ||
                !sshParameters.Contains(" -C")) {
                sshParameters += " -C";
            }

            int remotingPort = 0;
            if (useSshTunnel) {
                // find free remoting back-channel port
                TcpListener remotingPortListener = new TcpListener(IPAddress.Loopback, 0);
                remotingPortListener.Start();
                remotingPort = ((IPEndPoint)remotingPortListener.LocalEndpoint).Port;

                // find free local forward port
                TcpListener localForwardListener = new TcpListener(IPAddress.Loopback, 0);
                localForwardListener.Start();
                int localForwardPort = ((IPEndPoint)localForwardListener.LocalEndpoint).Port;

                // only stop the listeners after we got all ports we need
                // else it might re-use a port!
                remotingPortListener.Stop();
                localForwardListener.Stop();
            #if LOG4NET
                f_Logger.Debug("Connect(): found free local backward port (for remoting back-channel): " + remotingPort);
                f_Logger.Debug("Connect(): found free local forward port: " + localForwardPort);
            #endif

                // HACK: we can't use localForwardPort here as .NET remoting
                // will announce the server port in the server Session object
                // thus the client will try to reach it using the original
                // server port :(
                f_SshTunnelManager = new SshTunnelManager(
                    sshProgram, sshParameters, sshUsername, sshPassword,
                    sshKeyfile, sshHostname, sshPort,
                    //"127.0.0.1", localForwardPort, "127.0.0.1", port,
                    "127.0.0.1", port, "127.0.0.1", port,
                    "127.0.0.1", remotingPort, "127.0.0.1", remotingPort
                );
                f_SshTunnelManager.Setup();
                f_SshTunnelManager.Connect();

                // so we want to connect via the SSH tunnel now
                hostname = "127.0.0.1";
                // HACK: see above
                //port = localForwardPort;

                // the smuxi-server has to connect to us via the SSH tunnel too
                bindAddress = "127.0.0.1";
            }

            IDictionary props = new Hashtable();
            // ugly remoting expects the port as string ;)
            props["port"] = remotingPort.ToString();
            string connection_url = null;
            SessionManager sessm = null;
            switch (channel) {
                case "TCP":
                    // Make sure the channel is really using our random
                    // remotingPort. Already registered channel will for sure
                    // not to that and thus the back-connection fails!
                    if (f_ChannelName != null) {
                        IChannel oldChannel = ChannelServices.GetChannel(f_ChannelName);
                        if (oldChannel != null) {
            #if LOG4NET
                            f_Logger.Debug("Connect(): found old remoting channel, unregistering...");
            #endif
                            ChannelServices.UnregisterChannel(oldChannel);
                        }
                    }

                    // frontend -> engine
                    BinaryClientFormatterSinkProvider cprovider =
                        new BinaryClientFormatterSinkProvider();

                    // engine -> frontend (back-connection)
                    BinaryServerFormatterSinkProvider sprovider =
                        new BinaryServerFormatterSinkProvider();
                    // required for MS .NET 1.1
                    sprovider.TypeFilterLevel = TypeFilterLevel.Full;

                    if (bindAddress != null) {
                        props["machineName"] = bindAddress;
                    }
                    var tcpChannel = new TcpChannel(props, cprovider, sprovider);
                    f_ChannelName = tcpChannel.ChannelName;
                    ChannelServices.RegisterChannel(tcpChannel, false);

                    // make sure the listen port of channel is ready before we
                    // connect to the engine, as it will make a call back!
                    while (true) {
                        using (TcpClient tcpClient = new TcpClient()) {
                            try {
                                tcpClient.Connect(hostname, port);
            #if LOG4NET
                                f_Logger.Debug("Connect(): listen port of remoting channel is ready");
            #endif
                                break;
                            } catch (SocketException ex) {
            #if LOG4NET
                                f_Logger.Debug("Connect(): listen port of remoting channel is not reading yet, retrying...", ex);
            #endif
                            }
                            System.Threading.Thread.Sleep(1000);
                        }
                    }

                    connection_url = "tcp://"+hostname+":"+port+"/SessionManager";
            #if LOG4NET
                    f_Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
            #if CHANNEL_TCPEX
                case "TcpEx":
                    //props.Remove("port");
                    //props["name"] = "tcpex";
                    connection_url = "tcpex://"+hostname+":"+port+"/SessionManager";
                    if (ChannelServices.GetChannel("ExtendedTcp") == null) {
                        ChannelServices.RegisterChannel(new TcpExChannel(props, null, null));
                    }
            #if LOG4NET
                    _Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
            #endif
            #if CHANNEL_BIRDIRTCP
                case "BirDirTcp":
                    string ip = System.Net.Dns.Resolve(hostname).AddressList[0].ToString();
                    connection_url = "birdirtcp://"+ip+":"+port+"/SessionManager";
                    if (ChannelServices.GetChannel("birdirtcp") == null) {
                        ChannelServices.RegisterChannel(new BidirTcpClientChannel());
                    }
            #if LOG4NET
                    _Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
            #endif
                case "HTTP":
                    connection_url = "http://"+hostname+":"+port+"/SessionManager";
                    if (ChannelServices.GetChannel("http") == null) {
                        ChannelServices.RegisterChannel(new HttpChannel(), false);
                    }
            #if LOG4NET
                    f_Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
                default:
                    throw new ApplicationException(String.Format(
                                    _("Unknown channel ({0}) - "+
                                      "only the following channel types are supported:"),
                                    channel) + " HTTP TCP");
            }
            f_SessionManager = sessm;
            f_EngineUrl = connection_url;

            f_Session = sessm.Register(username, MD5.FromString(password), f_FrontendUI);
            if (f_Session == null) {
                throw new ApplicationException(_("Registration with engine failed!  "+
                               "The username and/or password were wrong - please verify them."));
            }

            f_EngineVersion = sessm.EngineVersion;
            f_UserConfig = new UserConfig(f_Session.Config,
                                         username);
            f_UserConfig.IsCaching = true;
            f_UserConfig.FrontendConfig = f_FrontendConfig;
        }
Esempio n. 3
0
        public static void Init()
        {
            if (_IsInitialized) {
                return;
            }
            _IsInitialized = true;

            Assembly asm = Assembly.GetAssembly(typeof(Engine));
            AssemblyName asm_name = asm.GetName(false);
            AssemblyProductAttribute pr = (AssemblyProductAttribute)asm.GetCustomAttributes(typeof(AssemblyProductAttribute), false)[0];
            _Version = asm_name.Version;
            _VersionNumber = asm_name.Version.ToString();
            _VersionString = String.Format("{0} {1} - running on {2} {3}", pr.Product, _Version, Platform.OperatingSystem, Platform.Architecture);

            _Config = new Config();
            _Config.Load();
            _Config.Save();

            string location = Assembly.GetExecutingAssembly().Location;
            _ProtocolManagerFactory = new ProtocolManagerFactory();
            _ProtocolManagerFactory.LoadAllProtocolManagers(Path.GetDirectoryName(location));

            _SessionManager = new SessionManager(_Config, _ProtocolManagerFactory);
        }
Esempio n. 4
0
        public static void Init()
        {
            if (_IsInitialized) {
                return;
            }
            _IsInitialized = true;

            var asm = Assembly.GetEntryAssembly();
            if (asm == null) {
                asm = Assembly.GetAssembly(typeof(Engine));
            }
            var asm_name = asm.GetName(false);

            var distVersion = Defines.DistVersion;
            if (!String.IsNullOrEmpty(distVersion)) {
                distVersion = String.Format(" ({0})", distVersion);
            }
            _VersionString = String.Format(
                "{0} {1}{2} - running on {3} {4}",
                Path.GetFileNameWithoutExtension(asm_name.Name),
                AssemblyVersion,
                distVersion,
                Platform.OperatingSystem,
                Platform.Architecture
            );

            _Config = new Config();
            _Config.Load();
            _Config.Save();

            string location = Path.GetDirectoryName(asm.Location);
            if (String.IsNullOrEmpty(location) &&
                Environment.OSVersion.Platform == PlatformID.Unix) {
                // we are mkbundled
                var locationBuilder = new StringBuilder(8192);
                if (Mono.Unix.Native.Syscall.readlink("/proc/self/exe", locationBuilder) >= 0) {
                    location = Path.GetDirectoryName(locationBuilder.ToString());
                }
            }
            _ProtocolManagerFactory = new ProtocolManagerFactory();
            _ProtocolManagerFactory.LoadAllProtocolManagers(location);

            _SessionManager = new SessionManager(_Config, _ProtocolManagerFactory);
        }
Esempio n. 5
0
 public static void InitSessionManager()
 {
     if (_SessionManager != null) {
         return;
     }
     if (_Config == null || _ProtocolManagerFactory == null) {
         throw new InvalidOperationException("Init() must be called first!");
     }
     _SessionManager = new SessionManager(_Config, _ProtocolManagerFactory);
 }
Esempio n. 6
0
        public void Connect(string engine)
        {
            Trace.Call(engine);

            f_Engine = engine;
            string username = (string) f_FrontendConfig["Engines/"+engine+"/Username"];
            string password = (string) f_FrontendConfig["Engines/"+engine+"/Password"];
            string hostname = (string) f_FrontendConfig["Engines/"+engine+"/Hostname"];
            string bindAddress = (string) f_FrontendConfig["Engines/"+engine+"/BindAddress"];
            int port = (int) f_FrontendConfig["Engines/"+engine+"/Port"];
            //string formatter = (string) _FrontendConfig["Engines/"+engine+"/Formatter"];
            string channel = (string) f_FrontendConfig["Engines/"+engine+"/Channel"];

            // SSH tunnel support
            bool useSshTunnel = false;
            if (f_FrontendConfig["Engines/"+engine+"/UseSshTunnel"] != null) {
                useSshTunnel = (bool) f_FrontendConfig["Engines/"+engine+"/UseSshTunnel"];
            }
            string sshProgram = (string) f_FrontendConfig["Engines/"+engine+"/SshProgram"];
            string sshHostname = (string) f_FrontendConfig["Engines/"+engine+"/SshHostname"];
            int sshPort = -1;
            if (f_FrontendConfig["Engines/"+engine+"/SshPort"] != null) {
                sshPort = (int) f_FrontendConfig["Engines/"+engine+"/SshPort"];
            }
            string sshUsername = (string) f_FrontendConfig["Engines/"+engine+"/SshUsername"];
            string sshPassword = (string) f_FrontendConfig["Engines/"+engine+"/SshPassword"];

            int remotingPort = 0;
            if (useSshTunnel) {
                // find free remoting back-channel port
                TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
                listener.Start();
                remotingPort = ((IPEndPoint)listener.LocalEndpoint).Port;
                listener.Stop();
            #if LOG4NET
                f_Logger.Debug("Connect(): found local free port for remoting back-channel: " + remotingPort);
            #endif

                if (String.IsNullOrEmpty(sshProgram)) {
                    // TODO: find ssh
                    sshProgram = "/usr/bin/ssh";
                }
                if (!File.Exists(sshProgram)) {
                    throw new ApplicationException(_("SSH client application was not found: " + sshProgram));
                }
                if (sshProgram.ToLower().EndsWith("putty.exe")) {
                    throw new ApplicationException(_("SSH client must be either OpenSSH (ssh) or Plink (plink.exe, _not_ putty.exe)"));
                }

                bool isPutty = false;
                if (sshProgram.ToLower().EndsWith("plink.exe")) {
                    isPutty = true;
                }

                SysDiag.ProcessStartInfo psi;
                if (isPutty) {
                    psi = CreatePlinkProcessStartInfo(hostname, port, remotingPort,
                                                      sshProgram, sshUsername,
                                                      sshPassword, null,
                                                      sshHostname, sshPort);
                } else {
                    psi = CreateOpenSshProcessStartInfo(hostname, port, remotingPort,
                                                        sshProgram, sshUsername,
                                                        sshPassword, null,
                                                        sshHostname, sshPort);
                }

            #if LOG4NET
                f_Logger.Debug("Connect(): setting up ssh tunnel using command: " + psi.FileName + " " + psi.Arguments);
            #endif
                f_SshTunnelProcess = SysDiag.Process.Start(psi);

                // HACK: give the process some time to fail (exiting)
                System.Threading.Thread.Sleep(2000);

                /*
                // wait till the tunnels are ready and timeout after 30 seconds
                bool exited = f_SshTunnelProcess.WaitForExit(30 * 1000);

                if (!exited) {
                    string msg = String.Format(_("Timeout setting SSH tunnel up (30 seconds)."));
            #if LOG4NET
                    f_Logger.Error("Connect(): " + msg);
                    f_Logger.Debug("Connect(): killing SSH tunnel process...");
            #endif
                    f_SshTunnelProcess.Kill();

                    throw new ApplicationException(msg);
                }
                */

                if (f_SshTunnelProcess.HasExited && f_SshTunnelProcess.ExitCode != 0) {
                    string output = f_SshTunnelProcess.StandardOutput.ReadToEnd();
                    string error = f_SshTunnelProcess.StandardError.ReadToEnd();
                    string msg = String.Format(
                        _("SSH tunnel setup failed with (exit code: {0})\n\n" +
                          "SSH program: {1}\n\n" +
                          "Program Error:\n" +
                          "{2}\n" +
                          "Prgram Output:\n" +
                          "{3}\n"),
                        f_SshTunnelProcess.ExitCode,
                        sshProgram,
                        error,
                        output
                    );
            #if LOG4NET
                    f_Logger.Error("Connect(): " + msg);
            #endif
                    throw new ApplicationException(msg);
                }

                // so we want connect to connect via the SSH tunnel now
                // (no need to override the port, as we use the same port as the smuxi-server)
                hostname = "127.0.0.1";

                // the smuxi-server has to connect via the SSH tunnel too
                bindAddress = "127.0.0.1";
            }

            IDictionary props = new Hashtable();
            // ugly remoting expects the port as string ;)
            props["port"] = remotingPort.ToString();
            string error_msg = null;
            string connection_url = null;
            SessionManager sessm = null;
            switch (channel) {
                case "TCP":
                    if (ChannelServices.GetChannel("tcp") == null) {
                        // frontend -> engine
                        BinaryClientFormatterSinkProvider cprovider =
                            new BinaryClientFormatterSinkProvider();

                        // engine -> frontend (back-connection)
                        BinaryServerFormatterSinkProvider sprovider =
                            new BinaryServerFormatterSinkProvider();
                        // required for MS .NET 1.1
                        sprovider.TypeFilterLevel = TypeFilterLevel.Full;

                        if (bindAddress != null) {
                            props["machineName"] = bindAddress;
                        }
                        ChannelServices.RegisterChannel(new TcpChannel(props, cprovider, sprovider), false);
                    }
                    connection_url = "tcp://"+hostname+":"+port+"/SessionManager";
            #if LOG4NET
                    f_Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
            #if CHANNEL_TCPEX
                case "TcpEx":
                    //props.Remove("port");
                    //props["name"] = "tcpex";
                    connection_url = "tcpex://"+hostname+":"+port+"/SessionManager";
                    if (ChannelServices.GetChannel("ExtendedTcp") == null) {
                        ChannelServices.RegisterChannel(new TcpExChannel(props, null, null));
                    }
            #if LOG4NET
                    _Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
            #endif
            #if CHANNEL_BIRDIRTCP
                case "BirDirTcp":
                    string ip = System.Net.Dns.Resolve(hostname).AddressList[0].ToString();
                    connection_url = "birdirtcp://"+ip+":"+port+"/SessionManager";
                    if (ChannelServices.GetChannel("birdirtcp") == null) {
                        ChannelServices.RegisterChannel(new BidirTcpClientChannel());
                    }
            #if LOG4NET
                    _Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
            #endif
                case "HTTP":
                    connection_url = "http://"+hostname+":"+port+"/SessionManager";
                    if (ChannelServices.GetChannel("http") == null) {
                        ChannelServices.RegisterChannel(new HttpChannel(), false);
                    }
            #if LOG4NET
                    f_Logger.Info("Connecting to: "+connection_url);
            #endif
                    sessm = (SessionManager)Activator.GetObject(typeof(SessionManager),
                        connection_url);
                    break;
                default:
                    throw new ApplicationException(String.Format(
                                    _("Unknown channel ({0}), "+
                                      "only following channel types are supported:"),
                                    channel) + " HTTP TCP");
            }
            f_SessionManager = sessm;
            f_EngineUrl = connection_url;

            f_Session = sessm.Register(username, MD5.FromString(password), f_FrontendUI);
            if (f_Session == null) {
                throw new ApplicationException(_("Registration at engine failed, "+
                               "username and/or password was wrong, please verify them."));
            }

            f_EngineVersion = sessm.EngineVersion;
            f_UserConfig = new UserConfig(f_Session.Config,
                                         username);
            f_UserConfig.IsCaching = true;
        }