Showing posts with label howto. Show all posts
Showing posts with label howto. Show all posts

Tuesday, November 10, 2009

Accessing the KDE Wallet from the Cmdline

I needed to write a script that would contact my Exchange server at work via IMAP and list all the messages in the Calendar folder. The idea was to see if it was possible to perform a one-way sync from the Exchange server to a specific calendar in Kontact. I was going to embed my IMAP password in the script - security hole, I know - but we have a password policy that requires the password to change every 30 days. Since I didn't want to edit the script every month I decided to see if it was possible to use the password for kmail that's already stored in my KDE wallet.

I didn't have any luck finding a perl interface to the KDE wallet. However, thanks to the good folks at #kde on freenode, I found that the KDE wallet - and lots of other applications as well - expose their interfaces over D-Bus. This was the first time I'd dealt with D-Bus so it took some getting used to but I figured out how to read my kmail password from my KDE wallet. KDE comes with the handy qdbus program that allows command-line testing of the D-Bus interface.

What follows are step-by-step instructions on how to use qdbus to open your KDE wallet and read your kmail password. I'll incorporate this into my one-way sync experiment using the Net::DBus perl module but I wanted to put this out there in case someone else was looking at that.

Introduction to qdbus
A quick intro to qdbus before we get started so you can explore other options instead of just kwalletd:

The following command shows all applications exposing a DBus interface:

$ qdbus

:1.50

org.gtk.vfs.Daemon
:1.51
:1.52
:1.54
org.kde.kwalletd
:1.56

org.kde.printer-applet-3206
:1.57
net.update-notifier-kde-3203
:1.58

The numbers and strings refer to applications, however since most applications expose a recognizable string it's common to use just the strings and ignore the numbers.

The following command lists all the DBus paths exposed by the kwalletd application:

$ qdbus org.kde.kwalletd
/
/MainApplication
/modules
/modules/kwalletd


The /MainApplication path is mainly used when you want to interact with the application itself and you'll find many applications that expose a /MainApplication path. I haven't explored this much but it looks like it should be interesting.

With that introduction to qdbus you should have enough to explore further on your own.

Getting a Password from a KDE Wallet
The following steps will open your default KDE wallet and get your kmail password. Each step will have an explanation, the command issued and the output of that command.

We will use the /modules/kwalletd path in the DBus interface for org.kde.kwalletd for all our password-getting needs. You can get a list of all the methods and signals exposed in the /modules/kwalletd path by using the following command:

$ qdbus org.kde.kwalletd /modules/kwalletd

method bool org.kde.KWallet.isOpen(QString wallet)
method bool org.kde.KWallet.isOpen(int handle)
method bool org.kde.KWallet.keyDoesNotExist(QString wallet, QString folder, QString key)
method QString org.kde.KWallet.localWallet()

method QString org.kde.KWallet.networkWallet()
method int org.kde.KWallet.open(QString wallet, qlonglong wId, QString appid)
method int org.kde.KWallet.openAsync(QString wallet, qlonglong wId, QString appid, bool handleSession)
method int org.kde.KWallet.openPath(QString path, qlonglong wId, QString appid)

Formatting's a bit messed up going forward. Not sure why :-(

However, let's get to work obtaining the password. First, we will open the default KDE wallet - called kdewallet. We will call the org.kde.KWallet.open method which expects a wallet name string, what appears to be a wallet id (similar to a file handle it seems) and finally an application id string. We will use "kdewallet" as the wallet name since that's the name of the default wallet in KDE. We don't know the value of the wallet id so we'll just specify 0. The application id is interesting because KDE wallet prompts the currently logged in user with the application id of any applications that call the org.kde.KWallet.open method which we're abbreviating to just open since that uniquely identifies it in the method list for the /modules/kwalletd path. Specifying a meaningful id here goes a long way to helping the user click on "Allow", "Allow Once" or "Allow Never". With all that in mind, let's use the following command:

$ qdbus org.kde.kwalletd /modules/kwalletd org.kde.KWallet.open kdewallet 0 "KOrganizer-Exchange 1-way Sync"

470467109

This results in popping up a dialog box like so:


For the purpose of these experiments, I chose "Allow Once". Once I've allowed it, the qdbus call returns a wallet id - similar to a file handle - that we'll use in all our other method calls. I did see that if I waited too long the dialog box remains visible but qdbus times out. However, the next time you make the
org.kde.KWallet.open call it returns a valid wallet id without prompting which means the permission grant is persistent. I'll have to deal with the timeouts in my perl code somehow. The next step is to see what's stored in my wallet. This isn't strictly necessary if you already know what you want but serves to walk through my own discovery process. Notice I'm passing in the newly given wallet id as well as the full application id as I sent earlier.

$ qdbus org.kde.kwalletd /modules/kwalletd folderList 470467109 "KOrganizer-Exchange 1-way Sync"

AdobeAIR
Amarok
Form Data
Network Management Passwords
bilbo
kblogger
kmail
mailtransports


Let's list the contents of the kmail folder:

$ qdbus org.kde.kwalletd /modules/kwalletd entryList 470467109 kmail "KOrganizer-Exchange 1-way Sync"

account-242017858
account-990222852


I know the account-242017858 account is the one I need the password from because the other account is older. So let's see how to retrieve that password:

$ qdbus org.kde.kwalletd /modules/kwalletd readPasswordList 470467109 kmail account-242017858 "KOrganizer-Exchange 1-way Sync"

account-242017858: [the password here]


There you go folks! That's all it takes. Please let me know if you found this helpful.

Tuesday, January 13, 2009

Recovering Virtual Machine Templates after Re-Installing VMware Virtual Center

If you have ESX servers managed by VMware Virtual Center chances are you've created templates of standard types of machines so deploying a new one becomes simpler. These templates are such time-savers that I tend to keep tweaking them with every new requirement until I have the perfect pristine CentOS or Win2k3 or FreeBSD host. Deploying a new virtual machine from a template is a cinch and the deployed machines always look identical - at least until you start customizing them. This means you can create scripts that run against a truly standard configuration and know that it will work the same way every time but I digress. This post is about what happens when you have to re-install VMware Virtual Center. This is something that I found two solutions for which both work well. However, the second solution is far simpler and less time-consuming.

The Easy Way
The first solution relies on the ability of VMware Infrastructure Client to convert a Template into a Virtual Machine and back. Since all virtual machines stored on ESX servers managed by a new instance of Virtual Center are automatically recognized and properly populated in the Virtual Infrastrucure Client, make sure you name every template to reflect that it's a template by e.g. putting the word "Template" somewhere in its name, etc.
  1. Switch your Virtual Infrastructure Client to display both virtual machines and templates by using the keyboard shortcut Ctrl-Shift-V or by clicking on dropdown associated with the large "Inventory" drop down in the top toolbar and choosing "Virtual Machines and Templates".
  2. Right-click on each template and choose "Convert to Virtual Machine".
  3. Once you've converted all your templates to virtual machines you can re-install Virtual Center.
  4. Now re-connect to the new instance of Virtual Center and you'll see all your templates as virtual machines.
  5. Right-click on each virtual machine that used to be a template (see where the naming comes in?) and click on "Convert to Template"
Voila! You now have your templates back. It does take some time to convert a template to a VM and back but it works.

The Elegant Way
This method doesn't require you to convert your templates to virtual machines and back. Just re-install your instance of Virtual Center and you will notice all your templates disappear the next time you connect to the new Virtual Center using your Virtual Infrastructure Client. Follow these steps to bring them back:
  1. Switch your Virtual Infrastructure Client to display your datastores by using the keyboard shortcut Ctrl-Shift-D or by clicking on dropdown associated with the large "Inventory" drop down in the top toolbar and choosing "Datastores".
  2. Click on a group and then a datastore and in the right detail panel click on "Browse Datastore...". This should bring up a window that will allow you to browse that datastore. Each virtual machine and template will have its own directory in this datastore.
  3. Click on a directory named after one of your templates. The right panel will change to show you all the files in that directory.
  4. Right click on the only file of type "Template VM" and click on "Add to Inventory".
  5. In the dialog box that pops up, give the template a name (presumably the same name as it currently has) and choose its location (presumably the same group it's in now).
  6. In the next dialog box choose the host to store the template on. This should be the same ESX server whose datastore you're browsing.
  7. After validating the template/vm it will present the last dialog of the wizard with the details of your "VM". Click "Finish" and you're done.
  8. Close the data store browser and change your Virtual Infrastructure Client to "Virtual Machines and Templates" mode using Ctrl-Shift-V or by clicking on Inventory and choosing "Virtual Machines and Templates" and you'll see the template back in the inventory!
Enjoy!