Logo Search packages:      
Sourcecode: f-spot version File versions

Ring.cs

//
// Gnome.Keyring.Ring.cs
//
// Authors:
//    Gonzalo Paniagua Javier (gonzalo@ximian.com)
//    Alp Toker (alp@atoker.com)
//
// (C) Copyright 2006 Novell, Inc. (http://www.novell.com)
// (C) Copyright 2007 Alp Toker
//

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;

using Mono.Unix;

#if WITH_DBUS
using NDesk.DBus;
#endif

namespace Gnome.Keyring {
      public class Ring {
            static string appname;

            private Ring ()
            {
            }

            public static string ApplicationName {
                  get {
                        if (appname == null) {
                              Assembly assembly = Assembly.GetEntryAssembly ();
                              if (assembly == null)
                                    throw new Exception ("You need to set Ring.ApplicationName.");
                              appname = assembly.GetName ().Name;
                        }

                        return appname;
                  }

                  set {
                        if (value == null || value == "")
                              throw new ArgumentException ("Cannot be null or empty", "value");

                        appname = value;
                  }
            }

            public static bool Available {
                  get {
                        Socket sock = Connect ();
                        if (sock != null) {
                              sock.Close ();
                              return true;
                        }
                        return false;
                  }
            }

            static Socket Connect ()
            {
                  string filename;
                  Socket sock;
             
                  filename = Environment.GetEnvironmentVariable ("GNOME_KEYRING_SOCKET");
                  sock = Connect (filename);

#if WITH_DBUS
                  if (sock == null) {
                        try {
                              filename = Bus.Session.GetObject<IDaemon> ("org.gnome.keyring", new ObjectPath ("/org/gnome/keyring/daemon")).GetSocketPath ();
                        } catch (Exception) {
                              filename = null;
                        }
                        sock = Connect (filename);
                  }
#endif

                  return sock;
            }

            static Socket Connect (string filename)
            {
                  if (filename == null || filename == "")
                        return null;

                  EndPoint ep = new UnixEndPoint (filename);
                  Socket sock = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
                  try {
                        sock.Connect (ep);
                  } catch (Exception) {
                        sock.Close ();
                        return null;
                  }
                  return sock;
            }

            static int GetInt32 (Socket sock)
            {
                  byte [] cuatro = new byte [4];
                  if (sock.Receive (cuatro) != 4)
                        throw new KeyringException (ResultCode.IOError);
                  return (cuatro [3] + (cuatro [2] << 8) + (cuatro [1] << 16) + (cuatro [0] << 24));
            }

            static byte [] one = new byte [1];
            static ResponseMessage SendRequest (MemoryStream stream)
            {
                  Socket sock = Connect ();
                  if (sock == null)
                        throw new KeyringException (ResultCode.NoKeyringDaemon);

                  try {
                        sock.Send (one); // Credentials byte
                        byte [] buffer = stream.ToArray ();
                        sock.Send (buffer);
                        int packet_size = GetInt32 (sock) - 4;
                        if (packet_size < 0)
                              throw new KeyringException (ResultCode.IOError);
                        byte [] response = new byte [packet_size];
                        int nbytes = sock.Receive (response);
                        if (nbytes != response.Length)
                              throw new KeyringException (ResultCode.IOError);
                        ResponseMessage resp = new ResponseMessage (response);
                        ResultCode result = (ResultCode) resp.GetInt32 ();
                        if (result != 0)
                              throw new KeyringException (result);

                        return resp;
                  } finally {
                        sock.Close ();
                  }
            }

            public static void LockAll ()
            {
                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.LockAll);
                  SendRequest (req.Stream);
            }

            public static void SetDefaultKeyring (string newKeyring)
            {
                  if (newKeyring == null)
                        throw new ArgumentNullException ("newKeyring");
                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.SetDefaultKeyring, newKeyring);
                  SendRequest (req.Stream);
            }

            public static string GetDefaultKeyring ()
            {
                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.GetDefaultKeyring);
                  ResponseMessage resp = SendRequest (req.Stream);
                  return resp.GetString ();
            }

            public static string [] GetKeyrings ()
            {
                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.ListKeyrings);
                  ResponseMessage resp = SendRequest (req.Stream);
                  return resp.GetStringList ();
            }

            public static void CreateKeyring (string name, string password)
            {
                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.CreateKeyring, name, password);
                  SendRequest (req.Stream);
            }

            public static void Lock (string keyring)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.LockKeyring, keyring);
                  SendRequest (req.Stream);
            }

            public static void Unlock (string keyring, string password)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  if (password == null)
                        throw new ArgumentNullException ("password");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.UnlockKeyring, keyring, password);
                  try {
                        SendRequest (req.Stream);
                  } catch (KeyringException ke) {
                        if (ke.ResultCode != ResultCode.AlreadyUnlocked)
                              throw;
                  }
            }

            public static void DeleteKeyring (string keyring)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.DeleteKeyring, keyring);
                  SendRequest (req.Stream);
            }

            public static int [] ListItemIDs (string keyring)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.ListItems, keyring);
                  ResponseMessage resp = SendRequest (req.Stream);
                  int len = resp.GetInt32 ();
                  int [] result = new int [len];
                  for (int i = 0; i < len; i++) {
                        result [i] = resp.GetInt32 ();
                  }

                  return result;
            }

            static ItemData [] empty_item_data = new ItemData [0];
            public static ItemData [] Find (ItemType type, Hashtable atts)
            {
                  if (atts == null)
                        throw new ArgumentNullException ("atts");
                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.Find);
                  req.Write ((int) type);
                  req.WriteAttributes (atts);
                  req.EndOperation ();

                  ResponseMessage resp = null;
                  try {
                        resp = SendRequest (req.Stream);
                  } catch (KeyringException ke) {
                        if (ke.ResultCode == ResultCode.Denied)
                              return empty_item_data;
                        throw;
                  }

                  ArrayList list = new ArrayList ();
                  while (resp.DataAvailable) {
                        ItemData found = ItemData.GetInstanceFromItemType (type);
                        found.Keyring = resp.GetString ();
                        found.ItemID = resp.GetInt32 ();
                        found.Secret = resp.GetString ();
                        found.Attributes = new Hashtable ();
                        resp.ReadAttributes (found.Attributes);
                        found.SetValuesFromAttributes ();
                        list.Add (found);
                  }

                  return (ItemData []) list.ToArray (typeof (ItemData));
            }

            static NetItemData [] empty_net_item_data = new NetItemData [0];
            public static NetItemData [] FindNetworkPassword (string user, string domain, string server, string obj,
                                                      string protocol, string authtype, int port)
            {
                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.Find);
                  req.Write ((int) ItemType.NetworkPassword);
                  Hashtable tbl = new Hashtable ();
                  tbl ["user"] = user;
                  tbl ["domain"] = domain;
                  tbl ["server"] = server;
                  tbl ["object"] = obj;
                  tbl ["protocol"] = protocol;
                  tbl ["authtype"] = authtype;
                  if (port != 0)
                        tbl ["port"] = port;
                  req.WriteAttributes (tbl);
                  req.EndOperation ();

                  ResponseMessage resp = null;
                  try {
                        resp = SendRequest (req.Stream);
                  } catch (KeyringException ke) {
                        if (ke.ResultCode == ResultCode.Denied)
                              return empty_net_item_data;
                        throw;
                  }
                  ArrayList list = new ArrayList ();
                  while (resp.DataAvailable) {
                        NetItemData found = new NetItemData ();
                        found.Keyring = resp.GetString ();
                        found.ItemID = resp.GetInt32 ();
                        found.Secret = resp.GetString ();
                        found.Attributes = new Hashtable ();
                        resp.ReadAttributes (found.Attributes);
                        found.SetValuesFromAttributes ();
                        list.Add (found);
                  }

                  return (NetItemData []) list.ToArray (typeof (NetItemData));
            }

            public static int CreateItem (string keyring, ItemType type, string displayName, Hashtable attributes,
                                    string secret, bool updateIfExists)
            {
                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.CreateItem);
                  req.Write (keyring);
                  req.Write (displayName);
                  req.Write (secret);
                  req.WriteAttributes (attributes);
                  req.Write ((int) type);
                  req.Write (updateIfExists ? 1 : 0);
                  req.EndOperation ();
                  ResponseMessage resp = SendRequest (req.Stream);
                  return resp.GetInt32 ();
            }

            public static void DeleteItem (string keyring, int id)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.DeleteItem, keyring, id);
                  SendRequest (req.Stream);
            }

            public static int CreateOrModifyNetworkPassword (string keyring, string user, string domain, string server, string obj,
                                                string protocol, string authtype, int port, string password)
            {
                  Hashtable tbl = new Hashtable ();
                  tbl ["user"] = user;
                  tbl ["domain"] = domain;
                  tbl ["server"] = server;
                  tbl ["object"] = obj;
                  tbl ["protocol"] = protocol;
                  tbl ["authtype"] = authtype;
                  if (port != 0)
                        tbl ["port"] = port;

                  string display_name;
                  if (port != 0)
                        display_name = String.Format ("{0}@{1}:{3}/{2}", user, server, obj, port);
                  else
                        display_name = String.Format ("{0}@{1}/{2}", user, server, obj);

                  return CreateItem (keyring, ItemType.NetworkPassword, display_name, tbl, password, true);
            }

            public static ItemData GetItemInfo (string keyring, int id)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.GetItemInfo, keyring, id);
                  ResponseMessage resp = SendRequest (req.Stream);
                  ItemType itype = (ItemType) resp.GetInt32 ();
                  ItemData item = ItemData.GetInstanceFromItemType (itype);
                  string name = resp.GetString ();
                  string secret = resp.GetString ();
                  DateTime mtime = resp.GetDateTime ();
                  DateTime ctime =  resp.GetDateTime ();
                  item.Keyring = keyring;
                  item.ItemID = id;
                  item.Secret = secret;
                  Hashtable tbl = new Hashtable ();
                  tbl ["name"] = name;
                  tbl ["keyring_ctime"] = ctime;
                  tbl ["keyring_mtime"] = mtime;
                  item.Attributes = tbl;
                  item.SetValuesFromAttributes ();
                  return item;
            }

            public static void SetItemInfo (string keyring, int id, ItemType type, string displayName, string secret)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.SetItemInfo);
                  req.Write (keyring);
                  req.Write (id);
                  req.Write ((int) type);
                  req.Write (displayName);
                  req.Write (secret);
                  req.EndOperation ();
                  SendRequest (req.Stream);
            }

            public static Hashtable GetItemAttributes (string keyring, int id)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.GetItemAttributes, keyring, id);
                  ResponseMessage resp = SendRequest (req.Stream);
                  Hashtable tbl = new Hashtable ();
                  resp.ReadAttributes (tbl);
                  return tbl;
            }

            public static void SetItemAttributes (string keyring, int id, Hashtable atts)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.SetItemAttributes);
                  req.Write (keyring);
                  req.Write (id);
                  req.WriteAttributes (atts);
                  req.EndOperation ();
                  SendRequest (req.Stream);
            }

            public static KeyringInfo GetKeyringInfo (string keyring)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.GetKeyringInfo, keyring);
                  ResponseMessage resp = SendRequest (req.Stream);
                  return new KeyringInfo (keyring, (resp.GetInt32 () != 0),
                                          resp.GetInt32 (),
                                          resp.GetDateTime (),
                                          resp.GetDateTime (),
                                          (resp.GetInt32 () != 0));
            }

            public static void SetKeyringInfo (string keyring, KeyringInfo info)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  if (info == null)
                        throw new ArgumentNullException ("info");

                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.SetKeyringInfo);
                  req.Write (keyring);
                  req.Write (info.LockOnIdle ? 1 : 0);
                  req.Write (info.LockTimeoutSeconds);
                  req.EndOperation ();
                  SendRequest (req.Stream);
            }

            public static ArrayList GetItemACL (string keyring, int id)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  RequestMessage req = new RequestMessage ();
                  req.CreateSimpleOperation (Operation.GetItemACL, keyring, id);
                  ResponseMessage resp = SendRequest (req.Stream);
                  int count = resp.GetInt32 ();
                  ArrayList list = new ArrayList (count);
                  for (int i = 0; i < count; i++) {
                        list.Add (new ItemACL (resp.GetString (), resp.GetString (), (AccessRights) resp.GetInt32 ()));
                  }
                  return list;
            }

            public static void SetItemACL (string keyring, int id, ICollection acls)
            {
                  if (acls == null)
                        throw new ArgumentNullException ("acls");

                  ItemACL [] arr = new ItemACL [acls.Count];
                  acls.CopyTo (arr, 0);
                  SetItemACL (keyring, id, arr);
            }

            public static void SetItemACL (string keyring, int id, ItemACL [] acls)
            {
                  if (keyring == null)
                        throw new ArgumentNullException ("keyring");

                  if (acls == null)
                        throw new ArgumentNullException ("acls");

                  if (acls.Length == 0)
                        throw new ArgumentException ("Empty ACL set.", "acls");

                  RequestMessage req = new RequestMessage ();
                  req.StartOperation (Operation.SetItemACL);
                  req.Write (keyring);
                  req.Write (id);
                  req.Write (acls.Length);
                  foreach (ItemACL acl in acls) {
                        req.Write (acl.DisplayName);
                        req.Write (acl.FullPath);
                        req.Write ((int) acl.Access);
                  }
                  req.EndOperation ();
                  SendRequest (req.Stream);
            }
      }

#if WITH_DBUS
      [Interface ("org.gnome.keyring.Daemon")]
      interface IDaemon
      {
            string GetSocketPath ();
      }
#endif
}


Generated by  Doxygen 1.6.0   Back to index