Rubyからgnome-keyringにアクセスする拡張ライブラリを作りました

RubyからWebとかにアクセスする事とか、よくある事だと思いますが
物騒な世の中なので生パスワードをファイルに保存するのは危険だし、
毎回入力するのも面倒だなーって感じです。
MacだとsecurityコマンドでKeychainにパスワードを預けたり取り出したりできるようです。


http://blog.netswitch.jp/articles/2009/12/19/use-keychain-for-termtter-on-mac
http://blog.netswitch.jp/articles/2009/12/19/use-keychain-for-termtter-on-mac


家の環境はUbuntuなのでKeychainは使えません。
なので、GNOMEのKeyringにパスワードを預けたり取り出したりする
Rubyの拡張ライブラリを作りました。


まず、libgnome-keyring-dev をインストールしておく必要があります。

$ sudo apt-get install libgnome-keyring-dev


次に以下をextconf.rbとgnome_keyring.cとして、同じディレクトリに置きます。

require 'mkmf'

GLIB = 'glib-2.0'
GNOME_KEYRING = 'gnome-keyring-1'

dir_config(GLIB,pkg_config(GLIB))
dir_config(GNOME_KEYRING,pkg_config(GNOME_KEYRING))

create_makefile('gnome_keyring')
#include "ruby.h"
#include <gnome-keyring.h>

static const char RubyKR[] = "RubyKeyring";
static const char RubyID[] = "ID";
static GnomeKeyringPasswordSchema schema = {
  GNOME_KEYRING_ITEM_GENERIC_SECRET,
  {
    { RubyKR, GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
    { RubyID, GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
    { NULL, 0 },
  }
};

static gchar display[] = "used by RubyKeyring.";

static VALUE keyring_get(VALUE self,VALUE key)
{
  VALUE retval;
  GnomeKeyringResult keyres;
  gchar *password = NULL;
  keyres = gnome_keyring_find_password_sync(&schema,
                                            &password,
					    RubyKR,RubyKR,
					    RubyID,StringValueCStr(key),
					    NULL
                                            );

  if( keyres == GNOME_KEYRING_RESULT_OK ){
    retval = rb_str_new_cstr(password);
    gnome_keyring_free_password(password);
  }
  else {
    retval = Qfalse;
  }

  return retval;
}

static VALUE keyring_set(VALUE self,VALUE id,VALUE password)
{
  if( password == Qnil ){
    gnome_keyring_delete_password_sync(&schema,
                                       RubyKR,RubyKR,
				       RubyID,StringValueCStr(id),
				       NULL);
  }
  else{
    gnome_keyring_store_password_sync(&schema,
                                      RubyKR,
                                      display,
                                      StringValueCStr(password),
                                      RubyKR,RubyKR,
                                      RubyID,StringValueCStr(id),
                                      NULL);
  }  return 0;
}

void Init_gnome_keyring()
{
  VALUE module;

  g_set_application_name("RubyGnomeKeyring");

  module = rb_define_module("GNOME_KEYRING");
  rb_define_module_function(module, "[]",keyring_get,1);
  rb_define_module_function(module ,"[]=",keyring_set,2);
}


置いたら以下のようにしてMakefileを作成してbuildします。

$ ruby extconf.rb
$ make


そしたら、gnome-keyring.soっていうファイルができているので
Rubyからrequireすれば使えます。つまり、gem作れって話ですね


使い方。メソッドは=しかありません。

GNOME_KEYRING['termtter@takkaw'] = 'foobar' #パスワード保存
GNOME_KEYRING['termtter@takkaw']             #パスワード参照
GNOME_KEYRING['termtter@takkaw'] = nil       #パスワード削除(nilを渡すと)


termtterで使う場合はconfigファイルと同じ所にライブラリを置いて
以下のようにすると良いでしょう。

require './gnome_keyring'
config.user_name = 'takkaw'
config.password = GNOME_KEYRING["termtter@"+config.user_name]


gnome-keyringに預けたパスワードは
GNOMEのメニューのアプリケーション=>アクセサリ=>パスワードと暗号鍵でも
管理(参照,変更,削除)が可能です


暇な時にgemを作りたいと思います。


参考URL
2008-12-05