public PuttyStartInfo(SessionData session) { string argsToLog = null; this.Executable = SuperPuTTY.Settings.PuttyExe; if (session.Proto == ConnectionProtocol.Cygterm) { CygtermStartInfo cyg = new CygtermStartInfo(session); this.Args = cyg.Args; this.WorkingDir = cyg.StartingDir; } else if (session.Proto == ConnectionProtocol.Mintty) { MinttyStartInfo mintty = new MinttyStartInfo(session); this.Args = mintty.Args; this.WorkingDir = mintty.StartingDir; this.Executable = SuperPuTTY.Settings.MinttyExe; } else { this.Args = MakeArgs(session, true); argsToLog = MakeArgs(session, false); } // attempt to parse env vars this.Args = this.Args.Contains('%') ? TryParseEnvVars(this.Args) : this.Args; Log.InfoFormat("Putty Args: '{0}'", argsToLog ?? this.Args); }
public PscpBrowserPanel(SessionData session, PscpOptions options, string localStartingDir) : this() { this.Name = session.SessionName; this.TabText = session.SessionName; //set the remote path String remotePath = ""; if (String.IsNullOrEmpty(session.RemotePath)){ remotePath = options.PscpHomePrefix + session.Username; }else{ remotePath = session.RemotePath; } //set the local path String localPath = ""; if (String.IsNullOrEmpty(localStartingDir)){ localPath = String.IsNullOrEmpty(session.LocalPath) ? Environment.GetFolderPath(Environment.SpecialFolder.Desktop) : session.LocalPath; }else{ localPath = localStartingDir; } this.fileTransferPresenter = new FileTransferPresenter(options); this.localBrowserPresenter = new BrowserPresenter( "Local", new LocalBrowserModel(), session, fileTransferPresenter); this.remoteBrowserPresenter = new BrowserPresenter( "Remote", new RemoteBrowserModel(options), session, fileTransferPresenter); this.browserViewLocal.Initialize(this.localBrowserPresenter, new BrowserFileInfo(new DirectoryInfo(localPath))); this.browserViewRemote.Initialize(this.remoteBrowserPresenter, RemoteBrowserModel.NewDirectory(remotePath)); this.fileTransferView.Initialize(this.fileTransferPresenter); }
/// <summary> /// Sync call to list directory contents /// </summary> /// <param name="session"></param> /// <param name="path"></param> /// <returns></returns> public ListDirectoryResult ListDirectory(SessionData session, BrowserFileInfo path) { ListDirectoryResult result; if (session == null || session.Username == null) { result = new ListDirectoryResult(path); result.ErrorMsg = "Session invalid"; result.StatusCode = ResultStatusCode.Error; } else { string targetPath = path.Path; if (targetPath == null || targetPath == ".") { targetPath = string.Format("/home/{0}", session.Username); Log.InfoFormat("Defaulting path: {0}->{1}", path.Path, targetPath); path.Path = targetPath; } PscpClient client = new PscpClient(this.Options, session); result = client.ListDirectory(path); } return result; }
public CygtermStartInfo(SessionData session) { this.session = session; // parse host args and starting dir Match m = Regex.Match(session.Host, LocalHost + ":(.*)"); String dir = m.Success ? m.Groups[1].Value : null; bool exists = false; if (dir != null) { exists = Directory.Exists(dir); Log.DebugFormat("Parsed dir from host. Host={0}, Dir={1}, Exists={2}", session.Host, dir, exists); } if (dir != null && exists) { // start bash...will start in process start dir this.Args = "-load \"" + session.PuttySession + "\" -cygterm bash -i "; this.StartingDir = dir; } else { // login shell // http://code.google.com/p/puttycyg/wiki/FAQ this.Args = "-load \"" + session.PuttySession + "\" -cygterm -"; } }
public static List<SessionData> GetAllSessionsFromPuTTY() { List<SessionData> sessions = new List<SessionData>(); RegistryKey key = RootAppKey; if (key != null) { string[] savedSessionNames = key.GetSubKeyNames(); foreach (string keyName in savedSessionNames) { RegistryKey sessionKey = key.OpenSubKey(keyName); if (sessionKey != null) { SessionData session = new SessionData(); session.Host = (string)sessionKey.GetValue("HostName", ""); session.Port = (int)sessionKey.GetValue("PortNumber", 22); session.Proto = (ConnectionProtocol)Enum.Parse(typeof(ConnectionProtocol), (string)sessionKey.GetValue("Protocol", "SSH"), true); session.PuttySession = (string)sessionKey.GetValue("PuttySession", HttpUtility.UrlDecode(keyName)); session.SessionName = HttpUtility.UrlDecode(keyName); session.Username = (string)sessionKey.GetValue("UserName", ""); sessions.Add(session); } } } return sessions; }
public MinttyStartInfo(SessionData session) { this.session = session; // parse host args and starting dir Match m = Regex.Match(session.Host, LocalHost + ":(.*)"); String dir = m.Success ? m.Groups[1].Value : null; bool exists = false; if (dir != null) { exists = Directory.Exists(dir); Log.DebugFormat("Parsed dir from host. Host={0}, Dir={1}, Exists={2}", session.Host, dir, exists); } if (dir != null && exists) { // start bash...will start in process start dir // >mintty.exe /bin/env CHERE_INVOKING=1 /bin/bash -l this.Args = "/bin/env CHERE_INVOKING=1 /bin/bash -l"; this.StartingDir = dir; } else { // login shell // http://code.google.com/p/puttycyg/wiki/FAQ this.Args = "-"; } }
static string MakeArgs(SessionData session, bool includePassword) { string args = "-" + session.Proto.ToString().ToLower() + " "; args += (!String.IsNullOrEmpty(session.Password) && session.Password.Length > 0) ? "-pw " + (includePassword ? session.Password : "******") + " " : ""; args += "-P " + session.Port + " "; args += (!String.IsNullOrEmpty(session.PuttySession)) ? "-load \"" + session.PuttySession + "\" " : ""; args += (!String.IsNullOrEmpty(session.ExtraArgs) ? session.ExtraArgs + " " : ""); args += (!String.IsNullOrEmpty(session.Username) && session.Username.Length > 0) ? " -l " + session.Username + " " : ""; args += session.Host; return args; }
public PscpBrowserPanel(SessionData session, PscpOptions options, string localStartingDir) : this() { this.Name = session.SessionName; this.TabText = session.SessionName; this.fileTransferPresenter = new FileTransferPresenter(options); this.localBrowserPresenter = new BrowserPresenter( "Local", new LocalBrowserModel(), session, fileTransferPresenter); this.remoteBrowserPresenter = new BrowserPresenter( "Remote", new RemoteBrowserModel(options), session, fileTransferPresenter); this.browserViewLocal.Initialize(this.localBrowserPresenter, new BrowserFileInfo(new DirectoryInfo(localStartingDir))); this.browserViewRemote.Initialize(this.remoteBrowserPresenter, RemoteBrowserModel.NewDirectory("/")); this.fileTransferView.Initialize(this.fileTransferPresenter); }
public ListDirectoryResult ListDirectory(SessionData session, BrowserFileInfo path) { Log.InfoFormat("GetFilesForPath, path={0}", path.Path); ListDirectoryResult result = new ListDirectoryResult(path); try { LoadDirectory(path, result); } catch (Exception ex) { result.SetError(null, ex); Log.ErrorFormat("Error loading directory: {0}", ex.Message); } return result; }
/// <summary> /// Open the filezilla program with the sesion data, for sftp connection. /// </summary> /// <param name="session"></param> public static void openFileZilla(SessionData session) { if (!String.IsNullOrEmpty(session.Password) && !SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg) Log.Warn("SuperPuTTY is set to NOT allow the use of the -pw <password> argument, this can be overriden in Tools -> Options -> GUI"); // open filezilla with the session info (https://wiki.filezilla-project.org/Command-line_arguments_%28Client%29) String pw = session.Password; String user = Uri.EscapeDataString(session.Username); String userPw = !String.IsNullOrEmpty(user) ? (!String.IsNullOrEmpty(pw) && SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg ? user + ":" + pw + "@" : user + "@") : ""; String userPwLog = !String.IsNullOrEmpty(user) ? (!String.IsNullOrEmpty(pw) && SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg ? user + ":" + "XXXXX" + "@" : user + "@") : ""; String rp = String.IsNullOrEmpty(session.RemotePath) ? "" : session.RemotePath; String lp = String.IsNullOrEmpty(session.LocalPath) ? "" : " --local=\"" + session.LocalPath + "\" "; String param = "sftp://" + userPw + session.Host + ":" + session.Port + rp + lp; Log.Debug("Send to FileZilla:" + SuperPuTTY.Settings.FileZillaExe + " params="+ "sftp://" + userPwLog + session.Host + ":" + session.Port + rp + lp); Process.Start(SuperPuTTY.Settings.FileZillaExe, param); }
/// <summary> /// Open the WinSCP program with the sesion data, for sftp connection. /// </summary> /// <param name="session"></param> public static void openWinSCP(SessionData session) { if (!String.IsNullOrEmpty(session.Password) && !SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg) Log.Warn("SuperPuTTY is set to NOT allow the use of the -pw <password> argument, this can be overriden in Tools -> Options -> GUI"); // open WinSCP with the session info (https://winscp.net/eng/docs/commandline) String pw = Uri.EscapeDataString(session.Password); String user = Uri.EscapeDataString(session.Username); String userPw = !String.IsNullOrEmpty(user) ? (!String.IsNullOrEmpty(pw) && SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg ? user + ":" + pw + "@" : user + "@") : ""; String userPwLog = !String.IsNullOrEmpty(user) ? (!String.IsNullOrEmpty(pw) && SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg ? user + ":" + "XXXXX" + "@" : user + "@") : ""; String rp = String.IsNullOrEmpty(session.RemotePath) ? "" : session.RemotePath; if (!rp.Substring(rp.Length).Equals("/")) { rp += "/"; } String lp = String.IsNullOrEmpty(session.LocalPath) ? "" : " -rawsettings localDirectory=\"" + session.LocalPath + "\" "; String param = "sftp://" + userPw + session.Host + ":" + session.Port + rp + lp; Log.Debug("Send to WinSCP:" + SuperPuTTY.Settings.WinSCPExe + " params="+ "sftp://" + userPwLog + session.Host + ":" + session.Port + rp + lp); Process.Start(SuperPuTTY.Settings.WinSCPExe, param); }
public BrowserPresenter(string name, IBrowserModel model, SessionData session, IFileTransferPresenter fileTransferPresenter) { this.Model = model; this.Session = session; this.FileTransferPresenter = fileTransferPresenter; this.FileTransferPresenter.ViewModel.FileTransfers.ListChanged += (FileTransfers_ListChanged); this.BackgroundWorker = new BackgroundWorker(); this.BackgroundWorker.WorkerReportsProgress = true; this.BackgroundWorker.WorkerSupportsCancellation = true; this.BackgroundWorker.DoWork += (BackgroundWorker_DoWork); this.BackgroundWorker.ProgressChanged += (BackgroundWorker_ProgressChanged); this.BackgroundWorker.RunWorkerCompleted += (BackgroundWorker_RunWorkerCompleted); this.ViewModel = new BrowserViewModel { Name = name, BrowserState = BrowserState.Ready }; }
static string MakeArgs(SessionData session, bool includePassword) { if (!String.IsNullOrEmpty(session.Password) && includePassword && !SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg) Log.Warn("SuperPuTTY is set to NOT allow the use of the -pw <password> argument, this can be overriden in Tools -> Options -> GUI"); string args = "-" + session.Proto.ToString().ToLower() + " "; args += !String.IsNullOrEmpty(session.Password) && session.Password.Length > 0 && SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg ? "-pw " + (includePassword ? session.Password : "******") + " " : ""; args += "-P " + session.Port + " "; args += !String.IsNullOrEmpty(session.PuttySession) ? "-load \"" + session.PuttySession + "\" " : ""; args += !String.IsNullOrEmpty(SuperPuTTY.Settings.PuttyDefaultParameters) ? SuperPuTTY.Settings.PuttyDefaultParameters + " " : ""; //If extra args contains the password, delete it (it's in session.password) string extraArgs = CommandLineOptions.replacePassword(session.ExtraArgs,""); args += !String.IsNullOrEmpty(extraArgs) ? extraArgs + " " : ""; args += !String.IsNullOrEmpty(session.Username) && session.Username.Length > 0 ? " -l " + session.Username + " " : ""; args += session.Host; return args; }
public object Clone() { SessionData session = new SessionData(); foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (pi.CanWrite) { pi.SetValue(session, pi.GetValue(this, null), null); } } return session; }
/// <summary> /// Read any existing saved sessions from the registry, decode and populate a list containing the data /// </summary> /// <returns>A list containing the entries retrieved from the registry</returns> public static List<SessionData> LoadSessionsFromRegistry() { Log.Info("LoadSessionsFromRegistry..."); List<SessionData> sessionList = new List<SessionData>(); RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Jim Radford\SuperPuTTY\Sessions"); if (key != null) { string[] sessionKeys = key.GetSubKeyNames(); foreach (string session in sessionKeys) { SessionData sessionData = new SessionData(); RegistryKey itemKey = key.OpenSubKey(session); if (itemKey != null) { sessionData.Host = (string)itemKey.GetValue("Host", ""); sessionData.Port = (int)itemKey.GetValue("Port", 22); sessionData.Proto = (ConnectionProtocol)Enum.Parse(typeof(ConnectionProtocol), (string)itemKey.GetValue("Proto", "SSH")); sessionData.PuttySession = (string)itemKey.GetValue("PuttySession", "Default Session"); sessionData.SessionName = session; sessionData.SessionId = (string)itemKey.GetValue("SessionId", session); sessionData.Username = (string)itemKey.GetValue("Login", ""); sessionData.LastDockstate = (DockState)itemKey.GetValue("Last Dock", DockState.Document); sessionData.AutoStartSession = bool.Parse((string)itemKey.GetValue("Auto Start", "False")); sessionList.Add(sessionData); } } } return sessionList; }
public void RunCombinedView() { Form form = new Form(); SessionData session = new SessionData { SessionId = "Test/SessionId", SessionName = "Test SessionName", Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; FileTransferPresenter fileTransferPresenter = new FileTransferPresenter(ScpConfig.DefaultOptions); FileTransferView fileTransferView = new FileTransferView(fileTransferPresenter) { Dock = DockStyle.Bottom }; BrowserView localBrowserView = new BrowserView( new BrowserPresenter("Local", new LocalBrowserModel(), session, fileTransferPresenter), new BrowserFileInfo(new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)))); localBrowserView.Dock = DockStyle.Fill; BrowserView remoteBrowserView = new BrowserView( new BrowserPresenter("Remote", new RemoteBrowserModel(ScpConfig.DefaultOptions), session, fileTransferPresenter), RemoteBrowserModel.NewDirectory("/home/" + ScpConfig.UserName)); remoteBrowserView.Dock = DockStyle.Fill; SplitContainer browserPanel = new SplitContainer() { Dock = DockStyle.Fill, SplitterDistance = 75, }; browserPanel.Panel1.Controls.Add(localBrowserView); browserPanel.Panel2.Controls.Add(remoteBrowserView); form.Controls.Add(browserPanel); form.Controls.Add(fileTransferView); form.Size = new Size(1024, 768); form.Show(); }
public void LocalToRemote() { SessionData session = new SessionData { Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; List<BrowserFileInfo> sourceFiles = new List<BrowserFileInfo> { //new BrowserFileInfo(new FileInfo(Path.GetTempFileName())) new BrowserFileInfo(new FileInfo(ScpConfig.PscpLocation)) }; BrowserFileInfo target = new BrowserFileInfo { Path = string.Format("/home/{0}/", session.Username), Source = SourceType.Remote }; PscpOptions options = new PscpOptions { PscpLocation = ScpConfig.PscpLocation, TimeoutMs = 5000 }; PscpClient client = new PscpClient(options, session); PscpResult res = client.CopyFiles( sourceFiles, target, (complete, cancelAll, status) => { Log.InfoFormat( "complete={0}, cancelAll={1}, fileName={2}, pctComplete={3}", complete, cancelAll, status.Filename, status.PercentComplete); }); Log.InfoFormat("Result: {0}", res); /* ListDirectoryResult res = client.ListDirectory(new BrowserFileInfo { Path = "." }); Assert.AreEqual(ResultStatusCode.Success, res.StatusCode); Assert.Greater(res.Files.Count, 0); foreach (BrowserFileInfo file in res.Files) { Log.Info(file); } Log.InfoFormat("Result: {0}", res);*/ }
public void ListDirBadPath() { SessionData session = new SessionData { Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; PscpClient client = new PscpClient(ScpConfig.DefaultOptions, session); ListDirectoryResult res = client.ListDirectory(new BrowserFileInfo { Path = "some_non_existant_dir" }); Assert.AreEqual(ResultStatusCode.Error, res.StatusCode); Assert.AreEqual(0, res.Files.Count); Assert.IsTrue(res.ErrorMsg != null && res.ErrorMsg.StartsWith("Unable to open")); Log.InfoFormat("Result: {0}", res); }
public void ListDirHostNoKey() { SessionData session = new SessionData { Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.UnKnownHost, Port = 22 }; PscpClient client = new PscpClient(ScpConfig.DefaultOptions, session); ListDirectoryResult res = client.ListDirectory(new BrowserFileInfo { Path = "." }); Assert.AreEqual(ResultStatusCode.Error, res.StatusCode); Assert.AreEqual(res.Files.Count, 0); Log.InfoFormat("Result: {0}", res); }
public PscpBrowserPanel(SessionData session, PscpOptions options) : this(session, options, Environment.GetFolderPath(Environment.SpecialFolder.Desktop)) { }
public void RunPscpBrowserPanel() { SessionData session = new SessionData { SessionId = "Test/SessionId", SessionName = "Test SessionName", Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; PscpBrowserPanel panel = new PscpBrowserPanel(session, ScpConfig.DefaultOptions); panel.Size = new Size(1024, 768); panel.Show(); }
public PscpBrowserPanel(SessionData session, PscpOptions options) : // default value of localStartingDir moved to localPath in PscpBrowserPanel(SessionData session, PscpOptions options, string localStartingDir) this(session, options, "") { }
public static string ToArgs(SessionData session, string password, string path) { StringBuilder sb = new StringBuilder(); sb.Append("-ls "); if (session.PuttySession != null) { sb.AppendFormat("-load \"{0}\" ", session.PuttySession); } //only send the password if AllowPlainTextPuttyPasswordArg is checked if (!String.IsNullOrEmpty(password) && !SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg) Log.Warn("SuperPuTTY is set to NOT allow the use of the -pw <password> argument, this can be overriden in Tools -> Options -> GUI"); //fix: use the parameter "password" if (!string.IsNullOrEmpty(password) && SuperPuTTY.Settings.AllowPlainTextPuttyPasswordArg) { sb.AppendFormat("-pw {0} ", password); } sb.AppendFormat("-P {0} ", session.Port); sb.AppendFormat("{0}@{1}:\"{2}\"", session.Username, session.Host, path); return sb.ToString(); }
public PscpClient(PscpOptions options, SessionData session) { this.Options = options; this.Session = session; }
static string ToArgs(SessionData session, string password, List<BrowserFileInfo> source, BrowserFileInfo target) { StringBuilder sb = new StringBuilder(); sb.Append("-r -agent "); // default arguments if (!String.IsNullOrEmpty(session.PuttySession)) { sb.Append("-load \"").Append(session.PuttySession).Append("\" "); } if (!String.IsNullOrEmpty(password)) { sb.Append("-pw ").Append(password).Append(" "); } sb.AppendFormat("-P {0} ", session.Port); if (target.Source == SourceType.Remote) { // possible to send multiple files remotely at a time foreach(BrowserFileInfo file in source) { sb.AppendFormat("\"{0}\" ", file.Path); } sb.AppendFormat(" {0}@{1}:\"{2}\"", session.Username, session.Host, EscapeForUnix(target.Path)); } else { if (source.Count > 1) { Log.WarnFormat("Not possible to transfer multiple remote files locally at one time. Tranfering first only!"); } sb.AppendFormat(" {0}@{1}:\"{2}\" ", session.Username, session.Host, EscapeForUnix(source[0].Path)); sb.AppendFormat("\"{0}\"", target.Path); } return sb.ToString(); }
public int CompareTo(object obj) { SessionData s = obj as SessionData; return(s == null ? 1 : this.SessionId.CompareTo(s.SessionId)); }
public void TestGUI() { Form form = new Form(); form.Size = new Size(600, 800); SessionData session = new SessionData { Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; BrowserPresenter presenter = new BrowserPresenter( "Remote", new RemoteBrowserModel(ScpConfig.DefaultOptions), session, new MockFileTransferPresenter()); BrowserView view = new BrowserView( presenter, RemoteBrowserModel.NewDirectory("/home/" + ScpConfig.UserName)); view.Dock = DockStyle.Fill; form.Controls.Add(view); form.ShowDialog(); }
public void ListDirSuccess() { SessionData session = new SessionData { Username = ScpConfig.UserName, Password = ScpConfig.Password, Host = ScpConfig.KnownHost, Port = 22 }; PscpClient client = new PscpClient(ScpConfig.DefaultOptions, session); ListDirectoryResult res = client.ListDirectory(new BrowserFileInfo { Path = "." }); Assert.AreEqual(ResultStatusCode.Success, res.StatusCode); Assert.Greater(res.Files.Count, 0); foreach (BrowserFileInfo file in res.Files) { Log.Info(file); } Log.InfoFormat("Result: {0}", res); }
public static string ToArgs(SessionData session, string password, string path) { StringBuilder sb = new StringBuilder(); sb.Append("-ls "); if (session.PuttySession != null) { sb.AppendFormat("-load \"{0}\" ", session.PuttySession); } if (!string.IsNullOrEmpty(session.Password)) { sb.AppendFormat("-pw {0} ", password); } sb.AppendFormat("-P {0} ", session.Port); sb.AppendFormat("{0}@{1}:{2}", session.Username, session.Host, path); return sb.ToString(); }
public static List<SessionData> GetAllSessionsFromPuTTYCM(string fileExport) { List<SessionData> sessions = new List<SessionData>(); if (fileExport == null || !File.Exists(fileExport)) { return sessions; } XmlDocument doc = new XmlDocument(); doc.Load(fileExport); XmlNodeList connections = doc.DocumentElement.SelectNodes("//connection[@type='PuTTY']"); foreach (XmlElement connection in connections) { List<string> folders = new List<string>(); XmlElement node = connection.ParentNode as XmlElement; while (node != null && node.Name != "root") { if (node.Name == "container" && node.GetAttribute("type") == "folder") { folders.Add(node.GetAttribute("name")); } node = node.ParentNode as XmlElement; } folders.Reverse(); string parentPath = string.Join("/", folders.ToArray()); XmlElement info = (XmlElement)connection.SelectSingleNode("connection_info"); XmlElement login = (XmlElement)connection.SelectSingleNode("login"); SessionData session = new SessionData(); session.SessionName = info.SelectSingleNode("name").InnerText; session.Host = info.SelectSingleNode("host").InnerText; session.Port = Convert.ToInt32(info.SelectSingleNode("port").InnerText); session.Proto = (ConnectionProtocol)Enum.Parse(typeof(ConnectionProtocol), info.SelectSingleNode("protocol").InnerText); session.PuttySession = info.SelectSingleNode("session").InnerText; session.SessionId = string.IsNullOrEmpty(parentPath) ? session.SessionName : SessionData.CombineSessionIds(parentPath, session.SessionName); session.Username = login.SelectSingleNode("login").InnerText; sessions.Add(session); } return sessions; }