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); }
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; }
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); }
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); }
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); }
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; }