private string FindXauthorityFile(X11ForwardingParams param)
        {
            string xauthPath;
            if (!String.IsNullOrEmpty(param.XauthorityFile)) {
                xauthPath = param.XauthorityFile;
            }
            else {
                var home = Environment.GetEnvironmentVariable("HOME");
                if (home == null) {
                    return null;
                }
                xauthPath = Path.Combine(home, ".Xauthority");
            }

            return File.Exists(xauthPath) ? xauthPath : null;
        }
        public void Deserialize(SSHLoginParameter tp, StructuredText node)
        {
            base.Deserialize(tp, node);
            tp.Method = "SSH1".Equals(node.Get("method")) ? SSHProtocol.SSH1 : SSHProtocol.SSH2;
            tp.AuthenticationType = ParseUtil.ParseEnum<AuthenticationType>(node.Get("authentication", ""), AuthenticationType.Password);
            tp.Account = node.Get("account", "");
            tp.IdentityFileName = node.Get("identityFileName", "");
            if (ProtocolsPlugin.Instance.ProtocolOptions.ReadSerializedPassword) {
                string pw = node.Get("passphrase", null);
                if (pw != null) {
                    tp.PasswordOrPassphrase = pw;
                    tp.LetUserInputPassword = false;
                }
                else {
                    pw = node.Get("password", null);
                    if (pw != null) {
                        pw = new SimpleStringEncrypt().DecryptString(pw);
                        if (pw != null) {
                            tp.PasswordOrPassphrase = pw;
                            tp.LetUserInputPassword = false;
                        }
                    }
                }
            }

            tp.EnableAgentForwarding = GetBoolValue(node, "enableAgentForwarding", false);

            tp.EnableX11Forwarding = GetBoolValue(node, "enableX11Forwarding", false);

            StructuredText x11Node = node.FindChild("x11Forwarding");
            if (x11Node != null) {
                int display = GetIntValue(x11Node, "display", 0);
                X11ForwardingParams x11params = new X11ForwardingParams(display);
                x11params.Screen = GetIntValue(x11Node, "screen", 0);
                x11params.NeedAuth = GetBoolValue(x11Node, "needAuth", false);
                x11params.XauthorityFile = x11Node.Get("xauthorityFile", null);
                x11params.UseCygwinUnixDomainSocket = GetBoolValue(x11Node, "useCygwinUnixDomainSocket", false);
                x11params.X11UnixFolder = x11Node.Get("x11UnixFolder", null);
                tp.X11Forwarding = x11params;
            }
        }
        /// <summary>
        /// Setup the connection manager according to the parameters.
        /// </summary>
        /// <param name="param">parameters</param>
        /// <exception cref="X11UtilException"></exception>
        /// <exception cref="X11SocketException"></exception>
        public void Setup(X11ForwardingParams param)
        {
            if (_setupDone) {
                return;
            }

            _param = param.Clone();

            _spoofedAuthProtocolName = DEFAULT_AUTH_NAME;
            _spoofedAuthCookie = GenerateCookie();

            if (param.UseCygwinUnixDomainSocket) {
                _protocolEventManager.Trace("[X11] Use Cygwin's domain socket");
                _socketFactory = () => new X11CygwinDomainSocket(param.X11UnixFolder);
            }
            else {
                _protocolEventManager.Trace("[X11] Use TCP socket");
                _socketFactory = () => new X11TcpSocket();
            }

            XauthorityEntry xauthEntry;
            if (param.NeedAuth) {
                string xauthFile = FindXauthorityFile(param);
                if (xauthFile == null) {
                    throw new X11UtilException(Strings.GetString("XauthorityFileNotFound"));
                }
                var parser = new XauthorityParser();
                xauthEntry = parser.FindBest(xauthFile, param.Display);
                if (xauthEntry == null) {
                    throw new X11UtilException(Strings.GetString("SuitableAuthorizationInformationNotFound"));
                }
            }
            else {
                xauthEntry = new XauthorityEntry(0, "", param.Display, "", new byte[0]);
            }

            var cookieInfo = GetUntrustedAccessCookie(_socketFactory, param.Display, xauthEntry);
            if (cookieInfo == null) {
                // no SECURITY extension
                _protocolEventManager.Trace("[X11] \"Trusted\" access will be used.");
                _xAuthProtocolName = xauthEntry.Name;
                _xAuthCookie = xauthEntry.Data;
                _authEntry = xauthEntry;
                _authId = null;
                _setupDone = true;
                return;
            }

            _protocolEventManager.Trace("[X11] \"Untrusted\" access will be used.");
            _xAuthProtocolName = DEFAULT_AUTH_NAME;
            _xAuthCookie = cookieInfo.Item2;
            _authEntry = xauthEntry;
            _authId = cookieInfo.Item1;
            _setupDone = true;
            // TODO:
            // the authorization cookie should be deleted from the X server when
            // the forwarding channel is closed.
        }