From 54135ecd9a96f59429cfd535f3add282b535d3e3 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 6 Jun 2012 22:54:16 -0400 Subject: Store session cookie in ccache for cli users Try to use the URI /ipa/session/xml if there is a key in the kernel keyring. If there is no cookie or it turns out to be invalid (expired, whatever) then use the standard URI /ipa/xml. This in turn will create a session that the user can then use later. https://fedorahosted.org/freeipa/ticket/2331 --- ipapython/kernel_keyring.py | 102 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 ipapython/kernel_keyring.py (limited to 'ipapython') diff --git a/ipapython/kernel_keyring.py b/ipapython/kernel_keyring.py new file mode 100644 index 000000000..547dd3de6 --- /dev/null +++ b/ipapython/kernel_keyring.py @@ -0,0 +1,102 @@ +# Authors: Rob Crittenden +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see . +# + +from ipapython.ipautil import run + +# NOTE: Absolute path not required for keyctl since we reset the environment +# in ipautil.run. + +# Use the session keyring so the same user can have a different principal +# in different shells. This was explicitly chosen over @us because then +# it is not possible to use KRB5CCNAME to have a different user principal. +# The same session would always be used and the first principal would +# always win. +KEYRING = '@s' +KEYTYPE = 'user' + +def dump_keys(): + """ + Dump all keys + """ + (stdout, stderr, rc) = run(['keyctl', 'list', KEYRING], raiseonerr=False) + return stdout + +def get_real_key(key): + """ + One cannot request a key based on the description it was created with + so find the one we're looking for. + """ + (stdout, stderr, rc) = run(['keyctl', 'search', KEYRING, KEYTYPE, key], raiseonerr=False) + if rc: + raise ValueError('key %s not found' % key) + return stdout.rstrip() + +def has_key(key): + """ + Returns True/False whether the key exists in the keyring. + """ + try: + get_real_key(key) + return True + except ValueError: + return False + +def read_key(key): + """ + Read the keyring and return the value for key. + + Use pipe instead of print here to ensure we always get the raw data. + """ + real_key = get_real_key(key) + (stdout, stderr, rc) = run(['keyctl', 'pipe', real_key], raiseonerr=False) + if rc: + raise ValueError('keyctl pipe failed: %s' % stderr) + + return stdout + +def update_key(key, value): + """ + Update the keyring data. If they key doesn't exist it is created. + """ + if has_key(key): + real_key = get_real_key(key) + (stdout, stderr, rc) = run(['keyctl', 'pupdate', real_key], stdin=value, raiseonerr=False) + if rc: + raise ValueError('keyctl pupdate failed: %s' % stderr) + else: + add_key(key, value) + +def add_key(key, value): + """ + Add a key to the kernel keyring. + """ + if has_key(key): + raise ValueError('key %s already exists' % key) + (stdout, stderr, rc) = run(['keyctl', 'padd', KEYTYPE, key, KEYRING], stdin=value, raiseonerr=False) + if rc: + raise ValueError('keyctl padd failed: %s' % stderr) + +def del_key(key): + """ + Remove a key from the keyring + """ + real_key = get_real_key(key) + (stdout, stderr, rc) = run(['keyctl', 'unlink', real_key, KEYRING], raiseonerr=False) + if rc: + raise ValueError('keyctl unlink failed: %s' % stderr) -- cgit