context: // 
  // lat - ConnectionManager.cs
  // Author: Loren Bandiera
  // Copyright 2005-2006 MMG Security, Inc.
  //
  // This program is free software; you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation; Version 2 
  //
  // This program is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with this program; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  //
  //
  
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.IO;
  using System.Xml;
  using GnomeKeyring;
  
  namespace lat
  {
  	public class Connection : IEqualityComparer<Connection>
  	{
  		ConnectionData settings;
  		LdapServer server;
  		ServerData data;
  		
  		List<string> serverViews;
  		List<string> attributeViewers;
  
  		public Connection (ConnectionData connectionData)
  		{
  			server = new LdapServer (connectionData);
  			data = new ServerData (server);
  			settings = connectionData;
  			
  			serverViews = new List<string> ();
  			attributeViewers = new List<string> ();			
  		}
  		
  		public void Bind (string userName, string userPass)
  		{
  			settings.UserName = userName;
  			settings.Pass = userPass;
  			
  			server.Bind (userName, userPass);
  		}
  		
  		public void Connect ()
  		{
  			if (settings.DontSavePassword) {
  				LoginDialog ld = new LoginDialog (settings.UserName);				
  				
  				bool res = ld.Run ();
  				if (res) {
  					settings.UserName = ld.UserName;
  					settings.Pass = ld.UserPass;
  				} else { settings.Pass = "dog"; }
  			}
  		
  			try {
  			
  				server.Connect (settings.Encryption);			
  				server.Bind (settings.UserName, settings.Pass);
  			
  				if (!server.Connected) {
  				
  					string msg = String.Format (
  						Mono.Unix.Catalog.GetString (
  						"Unable to connect to: ldap://{0}:{1}"),
  						server.Host, server.Port);
  				
  					throw new ApplicationException (msg);
  				}
  					
  				if (!server.Bound && settings.UserName != "") {
  				
  					string msg = String.Format (
  						Mono.Unix.Catalog.GetString (
  						"Unable to bind to: ldap://{0}:{1}"),
  						server.Host, server.Port);
  						
  					throw new ApplicationException (msg);
  				}
  
  			} catch (Exception e) {
  
  				Log.Debug (e);
  				throw;
  			}
  		}
  		
  		public void Disconnect ()
  		{
  			server.Disconnect ();
  		}
  		
  		public void StartTLS ()
  		{
  			server.StartTLS ();
  		}
  		
  		public override bool Equals (object obj)
  		{
  			if (obj is Connection)
  				return Equals (this, (Connection)obj);
  
  			return false;
  		}
  
  		public bool Equals (Connection lhs, Connection rhs)
  		{
  			if (lhs.Settings.Name.Equals (rhs.Settings.Name))
  				return true;
  
  			return false;
  		}
  
  		public override int GetHashCode ()
  		{
  			return GetHashCode (this);
  		}
  
  		public int GetHashCode (Connection conn)
  		{
  			return conn.Settings.Name.GetHashCode ();
  		}			
  			
  		public void SetDefaultAttributeViewers ()
  		{			
  			attributeViewers.Add ("lat.JpegAttributeViewPlugin");
  			attributeViewers.Add ("lat.PassswordAttributeViewPlugin");
  		}
  
  		public void SetDefaultServerViews ()
  		{
  			switch (settings.ServerType) {
  			
  			case LdapServerType.OpenLDAP:
  			case LdapServerType.FedoraDirectory:
  			case LdapServerType.Generic:
  				serverViews.Add ("lat.PosixComputerViewPlugin");
  				serverViews.Add ("lat.PosixContactsViewPlugin");
  				serverViews.Add ("lat.PosixGroupViewPlugin");
  				serverViews.Add ("lat.PosixUserViewPlugin");			
  				break;
  			
  			case LdapServerType.ActiveDirectory:
  				serverViews.Add ("lat.ActiveDirectoryComputerViewPlugin");
  				serverViews.Add ("lat.ActiveDirectoryContactsViewPlugin");
  				serverViews.Add ("lat.ActiveDirectoryGroupViewPlugin");
  				serverViews.Add ("lat.ActiveDirectoryUserViewPlugin");			
  				break;
  				
  			default:	
  				throw new ArgumentOutOfRangeException ("Invalid server type");
  			}			
  		}
  
  		public override string ToString ()
  		{
  			return settings.Name;
  		}
  
  		public ActiveDirectoryInfo ActiveDirectory
  		{
  			get { return server.ADInfo; }
  		}
  
  		public string AuthDN
  		{
  			get { return server.AuthDN; }
  		}
  
  		public string DirectoryRoot
  		{
  			get { return server.DirectoryRoot; }
  		}
  
  		public bool IsBound
  		{
  			get { return server.Bound; }
  		}
  
  		public bool IsConnected
  		{
  			get { return server.Connected; }
  		}
  		
  		public int Protocol
  		{
  			get { return server.Protocol; }
  		}
  		
  		public bool UseSSL
  		{
  			get { return server.UseSSL; }
  			set { server.UseSSL = value; }
  		}
  		
  		public ConnectionData Settings
  		{
  			get { return settings; }
  			set { settings = value; }
  		}
  		
  		public ServerData Data
  		{
  			get {
  				if (!this.IsConnected)
  					this.Connect ();
  						
  				return data;
  			}
  		}
  		
  		public List<string> ServerViews
  		{
  			get { return serverViews; }
  			set { serverViews = value; }
  		}
  		
  		public List<string> AttributeViewers
  		{
  			get { return attributeViewers; }
  			set { attributeViewers = value; }
  		}
  	}
  
  	public class ConnectionData
  	{
  		string name;
  		string hostName;
  		int port;
  		string directoryRoot;
  		string userName;
  		string password;
  		bool dontSavePassword;
  		EncryptionType encryptionType;
  		LdapServerType serverType;
  		bool dynamic;
  	
  		public ConnectionData()
  		{
  		}
  		
  		public ConnectionData(string name, string hostName, int port, string directoryRoot, string userName, bool savePassword, EncryptionType encryptionType, LdapServerType serverType, bool dynamic)
  		{
  			this.name = name;
  			this.hostName = hostName;
  			this.port = port;
  			this.directoryRoot = directoryRoot;
  			this.userName = userName;
  			this.dontSavePassword = savePassword;
  			this.encryptionType = encryptionType;
  			this.serverType = serverType;
  			this.dynamic = dynamic;
  		}
  		
  		public string Name
  		{
  			get { return name; }
  			set { name = value; }
  		}
  		
  		public string Host
  		{
  			get { return hostName; }
  			set { hostName = value; }
  		}
  		
  		public int Port
  		{
  			get { return port; }
  			set { port = value; }
  		}
  		
  		public string DirectoryRoot
  		{
  			get { return directoryRoot; }
  			set { directoryRoot = value; }
  		}
  		
  		public string UserName
  		{
  			get { return userName; }
  			set { userName = value; }
  		}
  		
  		public string Pass 
  		{
  			get {		
  				if (password == null) {
  					GnomeKeyring.Result gkr;
  					NetworkPasswordData[] list;
  
  					gkr = GnomeKeyring.Global.FindNetworkPassword (userName, out list);					
  					if (list.Length > 0) {
  						NetworkPasswordData npd = list[0];
  						password = npd.Password;
  					} else {
  						Log.Warn ("Unable to get password from GNOME keyring. Got result: {0}", gkr);
  					}
  				} 
  				
  				return password;
  			}
  			
  			set { password = value; }
  		}
  		
  		public bool DontSavePassword
  		{
  			get { return dontSavePassword; }
  			set { dontSavePassword = value; }
  		}
  		
  		public EncryptionType Encryption
  		{
  			get { return encryptionType; }
  			set { encryptionType = value; }
  		}
  		
  		public LdapServerType ServerType
  		{
  
gt: 			get { return serverType; }