Re: [Freeipa-devel] [PATCH] Password vault

2015-07-08 Thread Jan Cholasta

Dne 7.7.2015 v 16:42 Endi Sukma Dewata napsal(a):

- Original Message -

On 07/07/2015 10:51 AM, Jan Cholasta wrote:

Dne 3.7.2015 v 15:44 Endi Sukma Dewata napsal(a):

Here is the rebased patch for vault access control.



LGTM, except:

@@ -356,6 +386,13 @@ class vault(LDAPObject):
  {
  'objectclass': ['nsContainer'],
  'cn': rdn['cn'],
+'aci':
+'(targetfilter=(objectClass=ipaVault))' +
+'(version 3.0; ' +
+'acl User can manage private vaults; ' +
+'allow(read, search, compare, add, delete) ' +
+'userdn=ldap:///%s;;)'
+% owner_dn
  })

  # if entry can be added, return

I don't think dynamically creating ACIs with hardcoded userdn is something
we
want to do. This should be handled by a single ACI in cn=vaults.


+1. Single ACI like

+default: aci: (targetfilter=(objectClass=ipaVault))(version 3.0; acl
Vault
owners can manage the vault; allow(read, search, compare, write)
userattr=owner#USERDN;)

you already have there is more preferred.


New patch attached. For this to work the container itself needs an 'owner' 
attribute, so I changed the nsContainer into ipaVaultContainer.


I don't think that's really necessary on the top-level containers.

Anyway, the patch works, so ACK.

Pushed to master: bf6df3df9b388753a52a0040d9c15b1eabce41ca

--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-07-07 Thread Jan Cholasta

Dne 3.7.2015 v 15:44 Endi Sukma Dewata napsal(a):

Here is the rebased patch for vault access control.



LGTM, except:

@@ -356,6 +386,13 @@ class vault(LDAPObject):
 {
 'objectclass': ['nsContainer'],
 'cn': rdn['cn'],
+'aci':
+'(targetfilter=(objectClass=ipaVault))' +
+'(version 3.0; ' +
+'acl User can manage private vaults; ' +
+'allow(read, search, compare, add, delete) ' +
+'userdn=ldap:///%s;;)'
+% owner_dn
 })

 # if entry can be added, return

I don't think dynamically creating ACIs with hardcoded userdn is 
something we want to do. This should be handled by a single ACI in 
cn=vaults.


--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-07-07 Thread Jan Cholasta

Dne 3.7.2015 v 14:23 Endi Sukma Dewata napsal(a):

On 7/1/2015 1:53 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which
inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey
directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always
match attribute names. (Also I don't insist on the name
ipaVaultPublicKey, feel free to change it if you want.)


It's unchanged for now. In a previous discussion it was advised to
reuse
the existing attribute type whenever possible.


Well, in this discussion, it is not. Escrow public key should also
reuse
ipaPublicKey, but it can't if you use it for vault public key. By using
ipaPublicKey subtypes you can distinguish between the two uses and
still
use ipaPublicKey to refer to either of them.


So what's changed? This is what you said when I posted the same patch
six months ago:


In this patch I'm adding ipaVaultSalt and ipaVaultPublicKey attribute
types to store salt and public key for vault. Are there existing
attribute types that I can use instead? I see there's an ipaPublicKey,
should I use that and maybe add ipaSalt/ipaEncSalt? Thanks.


yes, please re-use existing attributes where possible.

Honza


What changed is that I now know there is also escrow public key, which I
didn't know six months ago.


Here's patch #368 to be applied on top of patch #357-5, but see comments
below.


Thanks for the patch.




Could you show me how to use ipaPublicKey to refer to ipaVaultPublicKey
and ipaEscrowPublicKey? Under what situation would that be useful?


For example for ipaPublicKey searches - if ipaVaultPublicKey and
ipaEscrowPublicKey both inherit from ipaPublicKey, then an ipaPublicKey
search will look in both ipaVaultPublicKey and ipaEscrowPublicKey. This
is not something we actually need right now, but once the schema is
done, it can't be fixed and I don't think we should prevent this,
especially since we can get it for free. BTW even the core LDAP schema
does this, see for example how the cn attribute inherits from the more
general name attribute:
https://tools.ietf.org/html/rfc4519#section-2.3.


I don't think that's how LDAP works.


It is, see https://tools.ietf.org/html/rfc4512#section-2.5.3.


The RFC doesn't say that either.
The cn does inherit from name, but if you search for name it won't
match/return cn. See queries below:

$ ldapsearch -LLL -x -b dc=example,dc=com (cn=Accounting Managers)
dn: cn=Accounting Managers,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfUniqueNames
cn: Accounting Managers
ou: groups
description: People who can manage accounting entries
uniqueMember: cn=Directory Manager

$ ldapsearch -LLL -x -b dc=example,dc=com (cn=Accounting Managers) \
   name
dn: cn=Accounting Managers,ou=Groups,dc=example,dc=com
(no cn attribute)

$ ldapsearch -LLL -x -b dc=example,dc=com (name=Accounting Managers)
(no result)


This seems like a bug in 389 DS, it works correctly with OpenLDAP:

$ ldapsearch -H ldap://localhost -D 'cn=Manager,dc=example,dc=com' -w 
password -b 'dc=example,dc=com' '(name=Manager)'

dn: cn=Manager,dc=example,dc=com
objectClass: organizationalRole
cn: Manager



Assuming this is what you meant, which doesn't seem to be working, is
there still a valid reason to add a new ipaVaultPublicKey instead of
using the existing ipaPublicKey?


I think everything mentioned in the RFC section I linked above is a good 
enough reason.





* CLI options will be identical to client and server API options (i.e.
no CLI-only, client-only, or server-only options)


Actually, you can create CLI-only options (add include='cli' to the
param's kwargs).


I need to look at this more closely. If I understand correctly in
user_del there are two 'preserve' options, the Bool preserve is for
client and server API, and the Flag preserve is for CLI. Wouldn't it be
better if they are stored in separate lists (or maybe separate classes)?
And it looks like you still need to delete the CLI options explicitly
anyway.


Well, it would be better if there was no Flag class at all and flags
were handled by CLI exclusively, because parameter classes should
reflect the data type (bool) and not the presentation (flag).


That indicates there should be a separation between client API and the
CLI too because, as you see in user_del, they can be different.


Not really, what there should be is separation between data type and 
presentation. This is what the web UI already does and so should the CLI.





Does the API.txt actually show the CLI options, the client API options,
or the server API options? I only see the Flag preserve, not the Bool

Re: [Freeipa-devel] [PATCH] Password vault

2015-07-07 Thread Martin Kosek
On 07/07/2015 10:51 AM, Jan Cholasta wrote:
 Dne 3.7.2015 v 15:44 Endi Sukma Dewata napsal(a):
 Here is the rebased patch for vault access control.

 
 LGTM, except:
 
 @@ -356,6 +386,13 @@ class vault(LDAPObject):
  {
  'objectclass': ['nsContainer'],
  'cn': rdn['cn'],
 +'aci':
 +'(targetfilter=(objectClass=ipaVault))' +
 +'(version 3.0; ' +
 +'acl User can manage private vaults; ' +
 +'allow(read, search, compare, add, delete) ' +
 +'userdn=ldap:///%s;;)'
 +% owner_dn
  })
 
  # if entry can be added, return
 
 I don't think dynamically creating ACIs with hardcoded userdn is something we
 want to do. This should be handled by a single ACI in cn=vaults.

+1. Single ACI like

+default: aci: (targetfilter=(objectClass=ipaVault))(version 3.0; acl Vault
owners can manage the vault; allow(read, search, compare, write)
userattr=owner#USERDN;)

you already have there is more preferred.

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-07-07 Thread Endi Sukma Dewata
- Original Message -
 On 07/07/2015 10:51 AM, Jan Cholasta wrote:
  Dne 3.7.2015 v 15:44 Endi Sukma Dewata napsal(a):
  Here is the rebased patch for vault access control.
 
  
  LGTM, except:
  
  @@ -356,6 +386,13 @@ class vault(LDAPObject):
   {
   'objectclass': ['nsContainer'],
   'cn': rdn['cn'],
  +'aci':
  +'(targetfilter=(objectClass=ipaVault))' +
  +'(version 3.0; ' +
  +'acl User can manage private vaults; ' +
  +'allow(read, search, compare, add, delete) ' +
  +'userdn=ldap:///%s;;)'
  +% owner_dn
   })
  
   # if entry can be added, return
  
  I don't think dynamically creating ACIs with hardcoded userdn is something
  we
  want to do. This should be handled by a single ACI in cn=vaults.
 
 +1. Single ACI like
 
 +default: aci: (targetfilter=(objectClass=ipaVault))(version 3.0; acl
 Vault
 owners can manage the vault; allow(read, search, compare, write)
 userattr=owner#USERDN;)
 
 you already have there is more preferred.

New patch attached. For this to work the container itself needs an 'owner' 
attribute, so I changed the nsContainer into ipaVaultContainer.

--
Endi S. Dewata
From 087f36b888e068ee732af6e0a2c24b1d50849ccd Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Fri, 17 Oct 2014 12:05:34 -0400
Subject: [PATCH] Added vault access control.

New LDAP ACIs have been added to allow vault owners to manage the
vaults and to allow members to access the vaults. New CLIs have
been added to manage the owner and member list. The LDAP schema
has been updated as well.

https://fedorahosted.org/freeipa/ticket/3872
---
 API.txt   |  92 +++
 VERSION   |   4 +-
 install/share/60basev3.ldif   |   3 +-
 install/share/vault.update|  15 +++-
 ipalib/plugins/vault.py   | 118 --
 ipatests/test_xmlrpc/test_vault_plugin.py |  27 +--
 6 files changed, 226 insertions(+), 33 deletions(-)

diff --git a/API.txt b/API.txt
index 99fa528733200fc3d797a9847b1d6df2188b92d5..98eaee8ce8b2804a6d34e42c3eff26ddb3851963 100644
--- a/API.txt
+++ b/API.txt
@@ -5422,27 +5422,58 @@ option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui
 option: Str('service?')
 option: Str('setattr*', cli_name='setattr', exclude='webui')
 option: Flag('shared?', autofill=True, default=False)
-option: Str('user?')
+option: Str('username?', cli_name='user')
 option: Str('version?', exclude='webui')
 output: Entry('result', type 'dict', Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
 command: vault_add_internal
-args: 1,10,3
+args: 1,11,3
 arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
 option: Bytes('ipavaultpublickey', attribute=True, cli_name='public_key', multivalue=False, required=False)
 option: Bytes('ipavaultsalt', attribute=True, cli_name='salt', multivalue=False, required=False)
 option: Str('ipavaulttype', attribute=True, autofill=True, cli_name='type', default=u'standard', multivalue=False, required=False)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('service?')
 option: Flag('shared?', autofill=True, default=False)
-option: Str('user?')
+option: Str('username?', cli_name='user')
 option: Str('version?', exclude='webui')
 output: Entry('result', type 'dict', Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
+command: vault_add_member
+args: 1,9,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user*', alwaysask=True, cli_name='users', csv=True)
+option: Str('username?', cli_name='user')
+option: 

Re: [Freeipa-devel] [PATCH] Password vault

2015-07-03 Thread Endi Sukma Dewata

On 7/1/2015 1:53 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which
inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey
directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always
match attribute names. (Also I don't insist on the name
ipaVaultPublicKey, feel free to change it if you want.)


It's unchanged for now. In a previous discussion it was advised to
reuse
the existing attribute type whenever possible.


Well, in this discussion, it is not. Escrow public key should also reuse
ipaPublicKey, but it can't if you use it for vault public key. By using
ipaPublicKey subtypes you can distinguish between the two uses and still
use ipaPublicKey to refer to either of them.


So what's changed? This is what you said when I posted the same patch
six months ago:


In this patch I'm adding ipaVaultSalt and ipaVaultPublicKey attribute
types to store salt and public key for vault. Are there existing
attribute types that I can use instead? I see there's an ipaPublicKey,
should I use that and maybe add ipaSalt/ipaEncSalt? Thanks.


yes, please re-use existing attributes where possible.

Honza


What changed is that I now know there is also escrow public key, which I
didn't know six months ago.


Here's patch #368 to be applied on top of patch #357-5, but see comments 
below.



Could you show me how to use ipaPublicKey to refer to ipaVaultPublicKey
and ipaEscrowPublicKey? Under what situation would that be useful?


For example for ipaPublicKey searches - if ipaVaultPublicKey and
ipaEscrowPublicKey both inherit from ipaPublicKey, then an ipaPublicKey
search will look in both ipaVaultPublicKey and ipaEscrowPublicKey. This
is not something we actually need right now, but once the schema is
done, it can't be fixed and I don't think we should prevent this,
especially since we can get it for free. BTW even the core LDAP schema
does this, see for example how the cn attribute inherits from the more
general name attribute: https://tools.ietf.org/html/rfc4519#section-2.3.


I don't think that's how LDAP works. The RFC doesn't say that either. 
The cn does inherit from name, but if you search for name it won't 
match/return cn. See queries below:


$ ldapsearch -LLL -x -b dc=example,dc=com (cn=Accounting Managers)
dn: cn=Accounting Managers,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfUniqueNames
cn: Accounting Managers
ou: groups
description: People who can manage accounting entries
uniqueMember: cn=Directory Manager

$ ldapsearch -LLL -x -b dc=example,dc=com (cn=Accounting Managers) \
  name
dn: cn=Accounting Managers,ou=Groups,dc=example,dc=com
(no cn attribute)

$ ldapsearch -LLL -x -b dc=example,dc=com (name=Accounting Managers)
(no result)

Assuming this is what you meant, which doesn't seem to be working, is 
there still a valid reason to add a new ipaVaultPublicKey instead of 
using the existing ipaPublicKey?



* CLI options will be identical to client and server API options (i.e.
no CLI-only, client-only, or server-only options)


Actually, you can create CLI-only options (add include='cli' to the
param's kwargs).


I need to look at this more closely. If I understand correctly in
user_del there are two 'preserve' options, the Bool preserve is for
client and server API, and the Flag preserve is for CLI. Wouldn't it be
better if they are stored in separate lists (or maybe separate classes)?
And it looks like you still need to delete the CLI options explicitly
anyway.


Well, it would be better if there was no Flag class at all and flags
were handled by CLI exclusively, because parameter classes should
reflect the data type (bool) and not the presentation (flag).


That indicates there should be a separation between client API and the 
CLI too because, as you see in user_del, they can be different.



Does the API.txt actually show the CLI options, the client API options,
or the server API options? I only see the Flag preserve, not the Bool
preserve.


It shows CLI options, see how the API object is initialized in makeapi.


Does that mean we're only doing the versioning on the CLI, and not the 
client API or server API? Suppose there are changes in client or server 
API that do not appear in API.txt but will affect the XML RPC, it might 
cause a compatibility problem. I think it just shows how convoluted the 
CLI, client API, and server API are in this framework.



* a plugin will only access one type of data (i.e. LDAP plugin can only
access LDAP data)


This is not assumed anywhere in the framework, you can access whatever
you want, but you can't expect baseldap to do 

Re: [Freeipa-devel] [PATCH] Password vault

2015-07-03 Thread Endi Sukma Dewata

Here is the rebased patch for vault access control.

--
Endi S. Dewata
From 6bec99d51552a6415c45d655f95627e341fae44b Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Fri, 17 Oct 2014 12:05:34 -0400
Subject: [PATCH] Added vault access control.

New LDAP ACIs have been added to allow vault owners to manage the
vaults and to allow members to access the vaults. New CLIs have
been added to manage the owner and member list. The LDAP schema
has been updated as well.

https://fedorahosted.org/freeipa/ticket/3872
---
 API.txt   |  92 ++
 VERSION   |   4 +-
 install/share/60basev3.ldif   |   2 +-
 install/share/vault.update|   5 ++
 ipalib/plugins/vault.py   | 122 --
 ipatests/test_xmlrpc/test_vault_plugin.py |  27 +--
 6 files changed, 224 insertions(+), 28 deletions(-)

diff --git a/API.txt b/API.txt
index 
d0ae1b72c2ae445a4e2cc168da5fd53f9a4de56d..c182098fe1017d46f9f7980c7b6891a1031f1068
 100644
--- a/API.txt
+++ b/API.txt
@@ -5341,27 +5341,58 @@ option: Flag('raw', autofill=True, cli_name='raw', 
default=False, exclude='webui
 option: Str('service?')
 option: Str('setattr*', cli_name='setattr', exclude='webui')
 option: Flag('shared?', autofill=True, default=False)
-option: Str('user?')
+option: Str('username?', cli_name='user')
 option: Str('version?', exclude='webui')
 output: Entry('result', type 'dict', Gettext('A dictionary representing an 
LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
 command: vault_add_internal
-args: 1,10,3
+args: 1,11,3
 arg: Str('cn', attribute=True, cli_name='name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, 
required=False)
 option: Bytes('ipavaultpublickey', attribute=True, cli_name='public_key', 
multivalue=False, required=False)
 option: Bytes('ipavaultsalt', attribute=True, cli_name='salt', 
multivalue=False, required=False)
 option: Str('ipavaulttype', attribute=True, autofill=True, cli_name='type', 
default=u'standard', multivalue=False, required=False)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, 
exclude='webui')
 option: Str('service?')
 option: Flag('shared?', autofill=True, default=False)
-option: Str('user?')
+option: Str('username?', cli_name='user')
 option: Str('version?', exclude='webui')
 output: Entry('result', type 'dict', Gettext('A dictionary representing an 
LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
+command: vault_add_member
+args: 1,9,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, 
required=True)
+option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
+option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, 
exclude='webui')
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user*', alwaysask=True, cli_name='users', csv=True)
+option: Str('username?', cli_name='user')
+option: Str('version?', exclude='webui')
+output: Output('completed', type 'int', None)
+output: Output('failed', type 'dict', None)
+output: Entry('result', type 'dict', Gettext('A dictionary representing an 
LDAP entry', domain='ipa', localedir=None))
+command: vault_add_owner
+args: 1,9,3
+arg: Str('cn', attribute=True, cli_name='name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, 
required=True)
+option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
+option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
+option: Flag('no_members', autofill=True, default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, 
exclude='webui')
+option: Str('service?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('user*', alwaysask=True, cli_name='users', csv=True)
+option: Str('username?', cli_name='user')
+option: Str('version?', exclude='webui')
+output: Output('completed', type 'int', None)
+output: Output('failed', type 'dict', None)
+output: Entry('result', type 'dict', Gettext('A dictionary representing an 
LDAP entry', domain='ipa', localedir=None))
 command: vault_archive
 args: 1,10,3
 arg: Str('cn', attribute=True, cli_name='name', 

Re: [Freeipa-devel] [PATCH] Password vault

2015-07-01 Thread Jan Cholasta

Dne 25.6.2015 v 19:01 Endi Sukma Dewata napsal(a):

On 6/25/2015 12:35 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey
directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always
match attribute names. (Also I don't insist on the name
ipaVaultPublicKey, feel free to change it if you want.)


It's unchanged for now. In a previous discussion it was advised to reuse
the existing attribute type whenever possible.


Well, in this discussion, it is not. Escrow public key should also reuse
ipaPublicKey, but it can't if you use it for vault public key. By using
ipaPublicKey subtypes you can distinguish between the two uses and still
use ipaPublicKey to refer to either of them.


So what's changed? This is what you said when I posted the same patch
six months ago:


In this patch I'm adding ipaVaultSalt and ipaVaultPublicKey attribute
types to store salt and public key for vault. Are there existing
attribute types that I can use instead? I see there's an ipaPublicKey,
should I use that and maybe add ipaSalt/ipaEncSalt? Thanks.


yes, please re-use existing attributes where possible.

Honza


What changed is that I now know there is also escrow public key, which I 
didn't know six months ago.




Could you show me how to use ipaPublicKey to refer to ipaVaultPublicKey
and ipaEscrowPublicKey? Under what situation would that be useful?


For example for ipaPublicKey searches - if ipaVaultPublicKey and 
ipaEscrowPublicKey both inherit from ipaPublicKey, then an ipaPublicKey 
search will look in both ipaVaultPublicKey and ipaEscrowPublicKey. This 
is not something we actually need right now, but once the schema is 
done, it can't be fixed and I don't think we should prevent this, 
especially since we can get it for free. BTW even the core LDAP schema 
does this, see for example how the cn attribute inherits from the more 
general name attribute: https://tools.ietf.org/html/rfc4519#section-2.3.





  a) When the non-split vault_{archive,retrieve} was called from a
server API with client-only options, it crashed. This is the broken API
I was talking about.


This is because in the current framework any API called on the server
side will be a server API, so you are not supposed to call it with
client options in the first place. Because of that limitation, the only
way to use client options is to use a separate API on the client side to
call the original API on the server side. The point is, client options
belong to client API, and server options belong to server API. In
vault_add the public key file name belongs to client API because it's
used to load a file on the client side. You should not add public key
file name option to the server API just because it can safely be
ignored.


I don't disagree, but file name options do not belong to the general
client API either, as they are strictly CLI-specific.


To my understanding the current framework doesn't have a separate CLI
class, so you don't have a choice but to put CLI-specific options in the
client API class too. However, you do have a choice not to combine
client API class and server API class because otherwise that will put
CLI-specific options in the server API class too.


Right.




2. Since the vault_archive_internal inherits from Update, it
accepts
all non
primary-key attributes automatically. This is incorrect since we
don't want to
update these parameters during archival. Can this behavior be
overridden?


Inherit from PKQuery instead (don't forget to add has_output =
output.standard_entry).


Previously you didn't want to use LDAPQuery because of semantics
reasons. Is PKQuery fine semantically?


It's not. Currently there is a set of commands which operate on the
LDAP
part of vault and another set of commands which operate on the KRA part
of vault and we don't want the commands in one set to see attributes
related to the other part of vault. If you insist on keeping both parts
in a single object, you have to resort to hackery like using PKQuery,
hence my suggestion to split the data part off to a separate object to
avoid this.


This because the framework was based on simplistic assumptions which
create unnecessary restrictions, for example:
* client API is just a proxy to server API (i.e. client and server
cannot do different things)


They can do different things the same way vault_archive/vault_retrieve
does that, the commands just can't be called the same (which is not
necessarily a bad thing).


Of course different APIs can do different things, like vault_add calling
vault_archive, 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-25 Thread Endi Sukma Dewata

On 6/25/2015 12:35 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey
directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always
match attribute names. (Also I don't insist on the name
ipaVaultPublicKey, feel free to change it if you want.)


It's unchanged for now. In a previous discussion it was advised to reuse
the existing attribute type whenever possible.


Well, in this discussion, it is not. Escrow public key should also reuse
ipaPublicKey, but it can't if you use it for vault public key. By using
ipaPublicKey subtypes you can distinguish between the two uses and still
use ipaPublicKey to refer to either of them.


So what's changed? This is what you said when I posted the same patch 
six months ago:



In this patch I'm adding ipaVaultSalt and ipaVaultPublicKey attribute
types to store salt and public key for vault. Are there existing
attribute types that I can use instead? I see there's an ipaPublicKey,
should I use that and maybe add ipaSalt/ipaEncSalt? Thanks.


yes, please re-use existing attributes where possible.

Honza


Could you show me how to use ipaPublicKey to refer to ipaVaultPublicKey 
and ipaEscrowPublicKey? Under what situation would that be useful?



  a) When the non-split vault_{archive,retrieve} was called from a
server API with client-only options, it crashed. This is the broken API
I was talking about.


This is because in the current framework any API called on the server
side will be a server API, so you are not supposed to call it with
client options in the first place. Because of that limitation, the only
way to use client options is to use a separate API on the client side to
call the original API on the server side. The point is, client options
belong to client API, and server options belong to server API. In
vault_add the public key file name belongs to client API because it's
used to load a file on the client side. You should not add public key
file name option to the server API just because it can safely be ignored.


I don't disagree, but file name options do not belong to the general
client API either, as they are strictly CLI-specific.


To my understanding the current framework doesn't have a separate CLI 
class, so you don't have a choice but to put CLI-specific options in the 
client API class too. However, you do have a choice not to combine 
client API class and server API class because otherwise that will put 
CLI-specific options in the server API class too.



2. Since the vault_archive_internal inherits from Update, it accepts
all non
primary-key attributes automatically. This is incorrect since we
don't want to
update these parameters during archival. Can this behavior be
overridden?


Inherit from PKQuery instead (don't forget to add has_output =
output.standard_entry).


Previously you didn't want to use LDAPQuery because of semantics
reasons. Is PKQuery fine semantically?


It's not. Currently there is a set of commands which operate on the LDAP
part of vault and another set of commands which operate on the KRA part
of vault and we don't want the commands in one set to see attributes
related to the other part of vault. If you insist on keeping both parts
in a single object, you have to resort to hackery like using PKQuery,
hence my suggestion to split the data part off to a separate object to
avoid this.


This because the framework was based on simplistic assumptions which
create unnecessary restrictions, for example:
* client API is just a proxy to server API (i.e. client and server
cannot do different things)


They can do different things the same way vault_archive/vault_retrieve
does that, the commands just can't be called the same (which is not
necessarily a bad thing).


Of course different APIs can do different things, like vault_add calling 
vault_archive, or vault_archive calling vault_archive_internal. The 
point is right now the client portion of an API (i.e. the forward() 
method) cannot do anything other than forwarding the request to the 
server, so the API has to be split into different APIs:


 * vault_archive
 * vault_archive_internal

It would be nice to have formal separation between client and server 
APIs so it's clear they are different but still related without 
resorting to ugly names:


 * client.vault_archive
 * server.vault_archive


* CLI options will be identical to client and server API options (i.e.
no CLI-only, client-only, or server-only options)


Actually, you can create CLI-only options (add include='cli' to the
param's kwargs).


I need to 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-24 Thread Jan Cholasta

Dne 23.6.2015 v 05:27 Endi Sukma Dewata napsal(a):

Please take a look at the new patch.

On 6/17/2015 1:32 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey
directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always
match attribute names. (Also I don't insist on the name
ipaVaultPublicKey, feel free to change it if you want.)


It's unchanged for now. In a previous discussion it was advised to reuse
the existing attribute type whenever possible.


Well, in this discussion, it is not. Escrow public key should also reuse 
ipaPublicKey, but it can't if you use it for vault public key. By using 
ipaPublicKey subtypes you can distinguish between the two uses and still 
use ipaPublicKey to refer to either of them.





1. The vault_add was split into a client-side vault_add and
server-side
vault_add_internal since the parameters are different (i.e. public
key file and
future escrow-related params). Since vault_add inherits from Local
all
non-primary-key attributes have to be added explicitly.


The split is not really necessary, since the only difference is the
public_key_file option, which exists only because of the lack of proper
file support in the framework. This is a different situation from
vault_{archive,retrieve}, which has two different sets of options on
client and server side. Escrow adds only ipaescrowpublickey and
escrow_public_key_file, right? If yes, we can safely keep the
command in
a single piece.


We know the vault-add will have at least two client-only parameters:
vault_public_key_file and escrow_public_key_file. Keeping these
parameters on the server API would be wrong and confusing. If the API is
called on the server side with vault_public_key_file the operation will
fail. In the previous discussion you considered this as broken API:


Server API is used not only by the server itself, but also by
installers
for example. Anyway the point is that there *can't* be a broken API
like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server
parts
would be preferable.


You are comparing apples and oranges:


Non-identical items are different by definition. Even between 2 apples
there are differences, but it doesn't mean the distinction is important.
The latest patch shows that the vault_add needs to be split, not just
because of the options, but because of what they do differently on the
client and server.


  a) When the non-split vault_{archive,retrieve} was called from a
server API with client-only options, it crashed. This is the broken API
I was talking about.


This is because in the current framework any API called on the server
side will be a server API, so you are not supposed to call it with
client options in the first place. Because of that limitation, the only
way to use client options is to use a separate API on the client side to
call the original API on the server side. The point is, client options
belong to client API, and server options belong to server API. In
vault_add the public key file name belongs to client API because it's
used to load a file on the client side. You should not add public key
file name option to the server API just because it can safely be ignored.


I don't disagree, but file name options do not belong to the general 
client API either, as they are strictly CLI-specific.





  b) The non-split vault_{archive,retrieve} had server-only options,
which were also accepted on client, but setting them had no effect.


Similarly, in a combined vault_add the public key file name option will
be accepted by the server, but it will be ignored. If something calls
vault_add on the server side and provides a file name, the operation
will crash too because the command expects the public key data to be
provided via another option. Splitting the vault_add into client and
server components avoids the potential problems.


  c) The CLI options to read param values from files should be generated
by the framework without having to specify dummy params. Once this is
implemented, the dummy params will go away. However, this will still
leave some client-only options in vault_{archive,retrieve}.


I'm not sure how the options will look like when that's implemented, but
regardless, the vault_add will still have client-only password option.


None of the above applies to vault_add - it does not have any
server-only options and the only client-only options it has are the
dummy options for file input, which are ignored on the 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-22 Thread Endi Sukma Dewata

Please take a look at the new patch.

On 6/17/2015 1:32 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always
match attribute names. (Also I don't insist on the name
ipaVaultPublicKey, feel free to change it if you want.)


It's unchanged for now. In a previous discussion it was advised to reuse 
the existing attribute type whenever possible.



1. The vault_add was split into a client-side vault_add and
server-side
vault_add_internal since the parameters are different (i.e. public
key file and
future escrow-related params). Since vault_add inherits from Local all
non-primary-key attributes have to be added explicitly.


The split is not really necessary, since the only difference is the
public_key_file option, which exists only because of the lack of proper
file support in the framework. This is a different situation from
vault_{archive,retrieve}, which has two different sets of options on
client and server side. Escrow adds only ipaescrowpublickey and
escrow_public_key_file, right? If yes, we can safely keep the command in
a single piece.


We know the vault-add will have at least two client-only parameters:
vault_public_key_file and escrow_public_key_file. Keeping these
parameters on the server API would be wrong and confusing. If the API is
called on the server side with vault_public_key_file the operation will
fail. In the previous discussion you considered this as broken API:


Server API is used not only by the server itself, but also by installers
for example. Anyway the point is that there *can't* be a broken API like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server parts
would be preferable.


You are comparing apples and oranges:


Non-identical items are different by definition. Even between 2 apples 
there are differences, but it doesn't mean the distinction is important. 
The latest patch shows that the vault_add needs to be split, not just 
because of the options, but because of what they do differently on the 
client and server.



  a) When the non-split vault_{archive,retrieve} was called from a
server API with client-only options, it crashed. This is the broken API
I was talking about.


This is because in the current framework any API called on the server 
side will be a server API, so you are not supposed to call it with 
client options in the first place. Because of that limitation, the only 
way to use client options is to use a separate API on the client side to 
call the original API on the server side. The point is, client options 
belong to client API, and server options belong to server API. In 
vault_add the public key file name belongs to client API because it's 
used to load a file on the client side. You should not add public key 
file name option to the server API just because it can safely be ignored.



  b) The non-split vault_{archive,retrieve} had server-only options,
which were also accepted on client, but setting them had no effect.


Similarly, in a combined vault_add the public key file name option will 
be accepted by the server, but it will be ignored. If something calls 
vault_add on the server side and provides a file name, the operation 
will crash too because the command expects the public key data to be 
provided via another option. Splitting the vault_add into client and 
server components avoids the potential problems.



  c) The CLI options to read param values from files should be generated
by the framework without having to specify dummy params. Once this is
implemented, the dummy params will go away. However, this will still
leave some client-only options in vault_{archive,retrieve}.


I'm not sure how the options will look like when that's implemented, but 
regardless, the vault_add will still have client-only password option.



None of the above applies to vault_add - it does not have any
server-only options and the only client-only options it has are the
dummy options for file input, which are ignored on the server.


Let's not get fixated with just the options. The vault_add will now 
archive a blank initial data as it was originally designed. The data can 
be used later to verify the vault password in subsequent archival 
operations. The vault_archive must be called by vault_add's client 
component since it takes a password and the password cannot be sent to 
the server.



Also, originally the vault was designed like this: when 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-17 Thread Jan Cholasta

Dne 16.6.2015 v 01:02 Endi Sukma Dewata napsal(a):

On 6/15/2015 2:22 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey

 ( 2.16.840.1.113730.3.8.18.2.? NAME 'ipaVaultPublicKey' DESC
'Assymetric vault public key as DER-encoded SubjectPublicKeyInfo (RFC
5280)' SUP ipaPublicKey EQUALITY octetStringMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )
 ( 2.16.840.1.113730.3.8.18.2.3 NAME 'ipaEscrowPublicKey' DESC 'IPA
escrow public key as DER-encoded SubjectPublicKeyInfo (RFC 5280)' SUP
ipaPublicKey EQUALITY octetStringMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )


OK. To be consistent the parameters need to be renamed too:
--vault-public-key and --vault-public-key-file.


It doesn't need to, there is no requirement for CLI names to always 
match attribute names. (Also I don't insist on the name 
ipaVaultPublicKey, feel free to change it if you want.)





1. The vault_add was split into a client-side vault_add and server-side
vault_add_internal since the parameters are different (i.e. public
key file and
future escrow-related params). Since vault_add inherits from Local all
non-primary-key attributes have to be added explicitly.


The split is not really necessary, since the only difference is the
public_key_file option, which exists only because of the lack of proper
file support in the framework. This is a different situation from
vault_{archive,retrieve}, which has two different sets of options on
client and server side. Escrow adds only ipaescrowpublickey and
escrow_public_key_file, right? If yes, we can safely keep the command in
a single piece.


We know the vault-add will have at least two client-only parameters:
vault_public_key_file and escrow_public_key_file. Keeping these
parameters on the server API would be wrong and confusing. If the API is
called on the server side with vault_public_key_file the operation will
fail. In the previous discussion you considered this as broken API:


Server API is used not only by the server itself, but also by installers
for example. Anyway the point is that there *can't* be a broken API like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server parts
would be preferable.


You are comparing apples and oranges:

 a) When the non-split vault_{archive,retrieve} was called from a 
server API with client-only options, it crashed. This is the broken API 
I was talking about.


 b) The non-split vault_{archive,retrieve} had server-only options, 
which were also accepted on client, but setting them had no effect.


 c) The CLI options to read param values from files should be generated 
by the framework without having to specify dummy params. Once this is 
implemented, the dummy params will go away. However, this will still 
leave some client-only options in vault_{archive,retrieve}.


None of the above applies to vault_add - it does not have any 
server-only options and the only client-only options it has are the 
dummy options for file input, which are ignored on the server.




Also, originally the vault was designed like this: when you create a
symmetric vault you're supposed to specify the password as well, similar
to adding a public key when creating an asymmetric vault. When you
archive, you're supposed to enter the same password for verification,
not a new password. So it would look like this:

$ ipa vault-add test --type symmetric
New password: 
Verify password: 

$ ipa vault-archive test --in secret1.txt
Password:  (same password)

$ ipa vault-archive test --in secret2.txt
Password:  (same password)

In the original design the vault-add would also archive a blank data,
which later could be used to verify the password during vault-archive by
decrypting the existing data first. There's also a plan to add a
mechanism to change the password after the ACL patch.

In the current design the vault-add doesn't archive anything, so during
vault-archive it cannot verify the password because there is nothing to
decrypt. In other words you can specify different passwords on each
archival, regardless of previous archivals:

$ ipa vault-add test --type symmetric

$ ipa vault-archive test --in secret1.txt
New password: 
Verify password: 

$ ipa vault-archive test --in secret2.txt
New password: 
Verify password: 

So basically here are the options:

1. Specify the crypto parameters once during vault creation, then
reuse/verify the parameters on each archival  retrieval. You can change
the parameters only with a special command.

2. Don't 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-15 Thread Endi Sukma Dewata

On 6/15/2015 2:22 AM, Jan Cholasta wrote:

I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey

 ( 2.16.840.1.113730.3.8.18.2.? NAME 'ipaVaultPublicKey' DESC
'Assymetric vault public key as DER-encoded SubjectPublicKeyInfo (RFC
5280)' SUP ipaPublicKey EQUALITY octetStringMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )
 ( 2.16.840.1.113730.3.8.18.2.3 NAME 'ipaEscrowPublicKey' DESC 'IPA
escrow public key as DER-encoded SubjectPublicKeyInfo (RFC 5280)' SUP
ipaPublicKey EQUALITY octetStringMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )


OK. To be consistent the parameters need to be renamed too: 
--vault-public-key and --vault-public-key-file.



1. The vault_add was split into a client-side vault_add and server-side
vault_add_internal since the parameters are different (i.e. public
key file and
future escrow-related params). Since vault_add inherits from Local all
non-primary-key attributes have to be added explicitly.


The split is not really necessary, since the only difference is the
public_key_file option, which exists only because of the lack of proper
file support in the framework. This is a different situation from
vault_{archive,retrieve}, which has two different sets of options on
client and server side. Escrow adds only ipaescrowpublickey and
escrow_public_key_file, right? If yes, we can safely keep the command in
a single piece.


We know the vault-add will have at least two client-only parameters: 
vault_public_key_file and escrow_public_key_file. Keeping these 
parameters on the server API would be wrong and confusing. If the API is 
called on the server side with vault_public_key_file the operation will 
fail. In the previous discussion you considered this as broken API:



Server API is used not only by the server itself, but also by installers
for example. Anyway the point is that there *can't* be a broken API like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server parts
would be preferable.


Also, originally the vault was designed like this: when you create a 
symmetric vault you're supposed to specify the password as well, similar 
to adding a public key when creating an asymmetric vault. When you 
archive, you're supposed to enter the same password for verification, 
not a new password. So it would look like this:


$ ipa vault-add test --type symmetric
New password: 
Verify password: 

$ ipa vault-archive test --in secret1.txt
Password:  (same password)

$ ipa vault-archive test --in secret2.txt
Password:  (same password)

In the original design the vault-add would also archive a blank data, 
which later could be used to verify the password during vault-archive by 
decrypting the existing data first. There's also a plan to add a 
mechanism to change the password after the ACL patch.


In the current design the vault-add doesn't archive anything, so during 
vault-archive it cannot verify the password because there is nothing to 
decrypt. In other words you can specify different passwords on each 
archival, regardless of previous archivals:


$ ipa vault-add test --type symmetric

$ ipa vault-archive test --in secret1.txt
New password: 
Verify password: 

$ ipa vault-archive test --in secret2.txt
New password: 
Verify password: 

So basically here are the options:

1. Specify the crypto parameters once during vault creation, then 
reuse/verify the parameters on each archival  retrieval. You can change 
the parameters only with a special command.


2. Don't specify the crypto parameters during vault creation, but 
specify new parameters on each archival. For retrieval you'd have to 
use/verify the parameters specified in the last archival.


I think the first one makes more sense and is easier to use. That also 
means the vault-add will have additional client-only parameters such as 
--password and --password-file.



2. Since the vault_archive_internal inherits from Update, it accepts
all non
primary-key attributes automatically. This is incorrect since we
don't want to
update these parameters during archival. Can this behavior be
overridden?


Inherit from PKQuery instead (don't forget to add has_output =
output.standard_entry).


Previously you didn't want to use LDAPQuery because of semantics 
reasons. Is PKQuery fine semantically? Why not use LDAPQuery since vault 
is an LDAPObject? And to be consistent should vault_retrieve_internal 
inherit from the same class?



BTW the correct solution would be to have a separate object and commands
for vault data (e.g. 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-15 Thread Jan Cholasta

Dne 10.6.2015 v 08:13 Martin Kosek napsal(a):

On 06/09/2015 11:13 PM, Endi Sukma Dewata wrote:

Please take a look at the attached patch to add symmetric  asymmetric vaults.
Some comments about the patch:


I think it would be better to use a new attribute type which inherits 
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey directly 
for assymetric vault public keys, so that assymetric public key and 
escrow public key are on the same level and you can still use 
ipaPublicKey to refer to either one:


ipaPublicKey
ipaVaultPublicKey
ipaEscrowPublicKey

( 2.16.840.1.113730.3.8.18.2.? NAME 'ipaVaultPublicKey' DESC 
'Assymetric vault public key as DER-encoded SubjectPublicKeyInfo (RFC 
5280)' SUP ipaPublicKey EQUALITY octetStringMatch SYNTAX 
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )
( 2.16.840.1.113730.3.8.18.2.3 NAME 'ipaEscrowPublicKey' DESC 'IPA 
escrow public key as DER-encoded SubjectPublicKeyInfo (RFC 5280)' SUP 
ipaPublicKey EQUALITY octetStringMatch SYNTAX 
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )




1. The vault_add was split into a client-side vault_add and server-side
vault_add_internal since the parameters are different (i.e. public key file and
future escrow-related params). Since vault_add inherits from Local all
non-primary-key attributes have to be added explicitly.


The split is not really necessary, since the only difference is the 
public_key_file option, which exists only because of the lack of proper 
file support in the framework. This is a different situation from 
vault_{archive,retrieve}, which has two different sets of options on 
client and server side. Escrow adds only ipaescrowpublickey and 
escrow_public_key_file, right? If yes, we can safely keep the command in 
a single piece.




2. Since the vault_archive_internal inherits from Update, it accepts all non
primary-key attributes automatically. This is incorrect since we don't want to
update these parameters during archival. Can this behavior be overridden?


Inherit from PKQuery instead (don't forget to add has_output = 
output.standard_entry).


BTW the correct solution would be to have a separate object and commands 
for vault data (e.g. vaultdata object, vault_archive - vaultdata_mod, 
vault_retrieve - vauldata_show), then we wouldn't have to deal with 
mixing vault attributes with vault data and could use proper crud base 
classes.




Just for the record, this changes API, right? It would be better to have this
in Alpha planned for this week. Not a blocker for Alpha though, we can give
warning that the internal API may change before GA.



--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-15 Thread Jan Cholasta

Dne 15.6.2015 v 09:22 Jan Cholasta napsal(a):

Dne 10.6.2015 v 08:13 Martin Kosek napsal(a):

On 06/09/2015 11:13 PM, Endi Sukma Dewata wrote:

Please take a look at the attached patch to add symmetric 
asymmetric vaults.
Some comments about the patch:


I think it would be better to use a new attribute type which inherits
from ipaPublicKey (ipaVaultPublicKey?) rather than ipaPublicKey directly
for assymetric vault public keys, so that assymetric public key and
escrow public key are on the same level and you can still use
ipaPublicKey to refer to either one:

 ipaPublicKey
 ipaVaultPublicKey
 ipaEscrowPublicKey

 ( 2.16.840.1.113730.3.8.18.2.? NAME 'ipaVaultPublicKey' DESC
'Assymetric vault public key as DER-encoded SubjectPublicKeyInfo (RFC
5280)' SUP ipaPublicKey EQUALITY octetStringMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )
 ( 2.16.840.1.113730.3.8.18.2.3 NAME 'ipaEscrowPublicKey' DESC 'IPA
escrow public key as DER-encoded SubjectPublicKeyInfo (RFC 5280)' SUP
ipaPublicKey EQUALITY octetStringMatch SYNTAX
1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'IPA v4.2' )



BTW what is the reason for that vault type is idendified by ipaVaultType 
attribute rather than object class?




1. The vault_add was split into a client-side vault_add and server-side
vault_add_internal since the parameters are different (i.e. public
key file and
future escrow-related params). Since vault_add inherits from Local all
non-primary-key attributes have to be added explicitly.


The split is not really necessary, since the only difference is the
public_key_file option, which exists only because of the lack of proper
file support in the framework. This is a different situation from
vault_{archive,retrieve}, which has two different sets of options on
client and server side. Escrow adds only ipaescrowpublickey and
escrow_public_key_file, right? If yes, we can safely keep the command in
a single piece.



2. Since the vault_archive_internal inherits from Update, it accepts
all non
primary-key attributes automatically. This is incorrect since we
don't want to
update these parameters during archival. Can this behavior be
overridden?


Inherit from PKQuery instead (don't forget to add has_output =
output.standard_entry).

BTW the correct solution would be to have a separate object and commands
for vault data (e.g. vaultdata object, vault_archive - vaultdata_mod,
vault_retrieve - vauldata_show), then we wouldn't have to deal with
mixing vault attributes with vault data and could use proper crud base
classes.



Just for the record, this changes API, right? It would be better to
have this
in Alpha planned for this week. Not a blocker for Alpha though, we can
give
warning that the internal API may change before GA.



--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-10 Thread Jan Cholasta

Dne 8.6.2015 v 12:04 Jan Cholasta napsal(a):

Dne 5.6.2015 v 21:50 Endi Sukma Dewata napsal(a):

On 6/5/2015 7:13 AM, Jan Cholasta wrote:

BTW, ipa-kra-install is broken with pki-core-10.2.4-1, but it works with
pki-core-10.2.1-3.


There's a bug in IPA: https://bugzilla.redhat.com/show_bug.cgi?id=1228671


Cloned the bug to https://fedorahosted.org/freeipa/ticket/5058.



The patch needs a rebase and version bumb (VERSION line at the top of
ipa-pki-proxy.conf).


I have bumped VERSION and rebased the patch, see attachment.

Pushed to master: 62ef11efad4ebbb8fa6f13a15c5ed8e833e90d43

--
Jan Cholasta
From 548636e6b1c7c0f921f882ec7510dc1365d4042a Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Mon, 8 Jun 2015 05:30:47 +
Subject: [PATCH] Fixed KRA installation problem.

The ipa-pki-proxy.conf has been modified to optionally require
client certificate authentication for PKI REST services as it's
done in standalone PKI to allow the proper KRA installation.

https://fedorahosted.org/freeipa/ticket/5058
---
 install/conf/ipa-pki-proxy.conf | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/install/conf/ipa-pki-proxy.conf b/install/conf/ipa-pki-proxy.conf
index 354b340..4b5b6f7 100644
--- a/install/conf/ipa-pki-proxy.conf
+++ b/install/conf/ipa-pki-proxy.conf
@@ -1,4 +1,4 @@
-# VERSION 7 - DO NOT REMOVE THIS LINE
+# VERSION 8 - DO NOT REMOVE THIS LINE
 
 ProxyRequests Off
 
@@ -11,7 +11,7 @@ ProxyRequests Off
 /LocationMatch
 
 # matches for admin port and installer
-LocationMatch ^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/rest/installer/installToken|^/ca/admin/ca/updateNumberRange|^/ca/rest/securityDomain/domainInfo|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/rest/securityDomain/installToken|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries|^/kra/rest/config/cert/transport
+LocationMatch ^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries
 NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
 NSSVerifyClient none
 ProxyPassMatch ajp://localhost:$DOGTAG_PORT
@@ -19,24 +19,25 @@ ProxyRequests Off
 /LocationMatch
 
 # matches for agent port and eeca port
-LocationMatch ^/ca/agent/ca/displayBySerial|^/ca/agent/ca/doRevoke|^/ca/agent/ca/doUnrevoke|^/ca/agent/ca/updateDomainXML|^/ca/eeca/ca/profileSubmitSSLClient|^/kra/agent/kra/connector|^/kra/rest/account|^/kra/rest/agent/keyrequests|^/kra/rest/agent/keys|^/ca/rest/admin/kraconnector/remove
+LocationMatch ^/ca/agent/ca/displayBySerial|^/ca/agent/ca/doRevoke|^/ca/agent/ca/doUnrevoke|^/ca/agent/ca/updateDomainXML|^/ca/eeca/ca/profileSubmitSSLClient|^/kra/agent/kra/connector
 NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
 NSSVerifyClient require
 ProxyPassMatch ajp://localhost:$DOGTAG_PORT
 ProxyPassReverse ajp://localhost:$DOGTAG_PORT
 /LocationMatch
 
-# matches for REST API
-LocationMatch ^/ca/rest/account/login|^/ca/rest/account/logout
+# matches for CA REST API
+LocationMatch ^/ca/rest/account/login|^/ca/rest/account/logout|^/ca/rest/installer/installToken|^/ca/rest/securityDomain/domainInfo|^/ca/rest/securityDomain/installToken|^/ca/rest/profiles|^/ca/rest/admin/kraconnector/remove
 NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
 NSSVerifyClient optional
 ProxyPassMatch ajp://localhost:$DOGTAG_PORT
 ProxyPassReverse ajp://localhost:$DOGTAG_PORT
 /LocationMatch
 
-LocationMatch ^/ca/rest/profiles
+# matches for KRA REST API
+LocationMatch ^/kra/rest/config/cert/transport|^/kra/rest/account|^/kra/rest/agent/keyrequests|^/kra/rest/agent/keys
 NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
-NSSVerifyClient none
+NSSVerifyClient optional
 ProxyPassMatch ajp://localhost:$DOGTAG_PORT
 ProxyPassReverse ajp://localhost:$DOGTAG_PORT
 /LocationMatch
-- 
2.1.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-08 Thread Jan Cholasta

Dne 5.6.2015 v 21:50 Endi Sukma Dewata napsal(a):

On 6/5/2015 7:13 AM, Jan Cholasta wrote:

If KRA is not installed, vault-archive and vault-retrieve fail with
internal error.


Added a code to check KRA installation in all vault commands. If you
know a way not to load the vault plugin if the KRA is not installed
please let me know, that's probably even better. Not sure how that will
work on the client side though.


I see this has been already resolved in the other thread.


The other thread was talking about removing the pki-base dependency on
the client side, but the vault plugin is still loaded on both client and
server regardless of KRA installation. Ideally the vault plugin should
not even be loaded so you cannot even execute the commands.


I don't agree - ideally the vault plugin should do the check at runtime, 
because it should work without httpd restart when KRA is installed on 
other replica. The KRA installer needs to be fixed in order to support 
this. I will provide a patch.





The commands still behave differently based on whether they were
called
from API which was initialized with in_server set to True or False.


That is unfortunately a restriction imposed by the framework. In order
to guarantee the security, the vault is designed to have separate
client
and server code. The client code encrypts the secret, the server code
forwards the encrypted secret to KRA. To archive a secret into a vault
properly, you are supposed to call the client code. If you're calling
the server code directly, you are responsible to do your own encryption
(i.e. generating session key, nonce, and vault data).


I understand why the code has to be separated, what I don't understand
is why it is in fact *not* separated and crammed into a single command,
making weird and undefined behavior possible.


If another plugin wants to use vault, it should implement a client code
which calls the vault client code to perform the archival from the
client side.

What is the use case for calling the vault API from the server side
anyway? Wouldn't that defeat the purpose of having a vault? If a secret
exists on the server side in an unencrypted form doesn't it mean the
secret may already have been compromised?


Server API is used not only by the server itself, but also by installers
for example. Anyway the point is that there *can't* be a broken API like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server parts
would be preferable.


There is no point in exposing the session_key, nonce and vault_data
options in CLI when their value is always overwritten in forward().


I agree there is no need to expose them in CLI, but in this framework
the API also defines the CLI. If there's a way to keep them in the
server API but not expose them in the CLI please let me know. Or, if
there's a way to define completely separate server API (without a
matching client CLI) and client CLI (without a matching server API)
that
will work too.


As I suggested above, you can split the commands into separate client
and server commands. The client command should inherit from
frontend.Local so that it is always executed locally and the server
command should have a NO_CLI = True attribute so that it is not
available in the CLI.


I see the vault_archive and vault_retrieve now inherit from PKQuery, and
there is a hack to execute the forward() even on the server side. A few
things below:

1. Why didn't you use frontend.Local as you initially suggested? If
there's a problem with frontend.Local please attach the ticket number in
the code.

2. The forward() can be merged into run(). There is no need to keep the
code in forward(). It would make more sense to have a run() method that
runs both on client and server, rather than a forward() that is supposed
to run on the client only but now forced to run on server too,
semantically speaking.


I have fixed the commands to inherit from Local.




Attached is a patch including the requested changes.

I have also changed vault_config to vaultconfig_show, for consistency
with {,dns}config_show (it also makes the transport certificate
retrieval code in vault_{archive,retrieve} simpler).


3. The parameter description for nonce should be just 'Nonce' instead of
'Nonce encrypted'.


Fixed.



4. There's a PEP8 error.


Fixed.



5. The VERSION needs to be updated.


Fixed.



Assuming the above issues are addressed, ACK.


OK, pushed to master: df1bd39a43f30138cf55e0e7720fa3dec1d912e0




I have noticed that triple-length DES is used for the session key.
Wouldn't AES be better?

 # generate session key
 mechanism = nss.CKM_DES3_CBC_PAD


That's the default used by the KRA's client library, and that's what the
KRA has been tested with. We probably can change it to AES later. It
shouldn't be blocking this patch.


OK, no problem.




BTW, ipa-kra-install is broken with pki-core-10.2.4-1, but it works with

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-05 Thread Jan Cholasta

Dne 3.6.2015 v 14:17 Jan Cholasta napsal(a):

Dne 2.6.2015 v 02:00 Endi Sukma Dewata napsal(a):

Please take a look at the updated patch.

On 5/27/2015 12:39 AM, Jan Cholasta wrote:

21) vault_archive is not a retrieve operation, it should be
based on
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it
does
not do anything with LDAP. The same applies to vault_retrieve.


The vault_archive does not actually modify the LDAP entry
because it
stores the data in KRA. It is actually an LDAPRetrieve operation
because
it needs to get the vault info before it can perform the archival
operation. Same thing with vault_retrieve.


It is not a LDAPRetrieve operation, because it has different
semantics.
Please use Command as base class and either use ldap2 for direct
LDAP or
call vault_show instead of hacking around LDAPRetrieve.


It's been changed to inherit from LDAPQuery instead.


NACK, it's not a LDAPQuery operation, because it has different
semantics. There is more to a command than executing code, so you
should
use a correct base class.


Changed to inherit from Command as requested. Now these commands no
longer have a direct access to the vault object (self.obj) although
they
are accessing vault objects like other vault commands. Also now the
vault name argument has to be added explicitly on each command.


You can inherit from crud.Retrieve and crud.Update to get self.obj and
the argument back.


I tried this:

   class vault_retrieve(Command, crud.Retrieve):

and it gave me an error:

   TypeError: Error when calling the metaclass bases
   Cannot create a consistent method resolution
   order (MRO) for bases Retrieve, Command

I'm sticking with the original code since it works fine although not
ideal. I'm not a Python expert, so if you know how to fix this properly
please feel free to post a patch on top of this.


The class hierarchy is as follows:

frontend.Command
frontend.Method
crud.PKQuery
crud.Retrieve
cdur.Update

So removing Command from the list of base classes should fix it.




If KRA is not installed, vault-archive and vault-retrieve fail with
internal error.


Added a code to check KRA installation in all vault commands. If you
know a way not to load the vault plugin if the KRA is not installed
please let me know, that's probably even better. Not sure how that will
work on the client side though.


I see this has been already resolved in the other thread.




The commands still behave differently based on whether they were called
from API which was initialized with in_server set to True or False.


That is unfortunately a restriction imposed by the framework. In order
to guarantee the security, the vault is designed to have separate client
and server code. The client code encrypts the secret, the server code
forwards the encrypted secret to KRA. To archive a secret into a vault
properly, you are supposed to call the client code. If you're calling
the server code directly, you are responsible to do your own encryption
(i.e. generating session key, nonce, and vault data).


I understand why the code has to be separated, what I don't understand
is why it is in fact *not* separated and crammed into a single command,
making weird and undefined behavior possible.



If another plugin wants to use vault, it should implement a client code
which calls the vault client code to perform the archival from the
client side.

What is the use case for calling the vault API from the server side
anyway? Wouldn't that defeat the purpose of having a vault? If a secret
exists on the server side in an unencrypted form doesn't it mean the
secret may already have been compromised?


Server API is used not only by the server itself, but also by installers
for example. Anyway the point is that there *can't* be a broken API like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server parts
would be preferable.




There is no point in exposing the session_key, nonce and vault_data
options in CLI when their value is always overwritten in forward().


I agree there is no need to expose them in CLI, but in this framework
the API also defines the CLI. If there's a way to keep them in the
server API but not expose them in the CLI please let me know. Or, if
there's a way to define completely separate server API (without a
matching client CLI) and client CLI (without a matching server API) that
will work too.


As I suggested above, you can split the commands into separate client
and server commands. The client command should inherit from
frontend.Local so that it is always executed locally and the server
command should have a NO_CLI = True attribute so that it is not
available in the CLI.




Will this always succeed?

+# deactivate vault record in KRA
+response = kra_client.keys.list_keys(
+client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)



Re: [Freeipa-devel] [PATCH] Password vault

2015-06-05 Thread Endi Sukma Dewata

On 6/5/2015 7:13 AM, Jan Cholasta wrote:

If KRA is not installed, vault-archive and vault-retrieve fail with
internal error.


Added a code to check KRA installation in all vault commands. If you
know a way not to load the vault plugin if the KRA is not installed
please let me know, that's probably even better. Not sure how that will
work on the client side though.


I see this has been already resolved in the other thread.


The other thread was talking about removing the pki-base dependency on 
the client side, but the vault plugin is still loaded on both client and 
server regardless of KRA installation. Ideally the vault plugin should 
not even be loaded so you cannot even execute the commands.



The commands still behave differently based on whether they were called
from API which was initialized with in_server set to True or False.


That is unfortunately a restriction imposed by the framework. In order
to guarantee the security, the vault is designed to have separate client
and server code. The client code encrypts the secret, the server code
forwards the encrypted secret to KRA. To archive a secret into a vault
properly, you are supposed to call the client code. If you're calling
the server code directly, you are responsible to do your own encryption
(i.e. generating session key, nonce, and vault data).


I understand why the code has to be separated, what I don't understand
is why it is in fact *not* separated and crammed into a single command,
making weird and undefined behavior possible.


If another plugin wants to use vault, it should implement a client code
which calls the vault client code to perform the archival from the
client side.

What is the use case for calling the vault API from the server side
anyway? Wouldn't that defeat the purpose of having a vault? If a secret
exists on the server side in an unencrypted form doesn't it mean the
secret may already have been compromised?


Server API is used not only by the server itself, but also by installers
for example. Anyway the point is that there *can't* be a broken API like
this, you should at least raise an error if the command is called from
server API, although actually separating it into client and server parts
would be preferable.


There is no point in exposing the session_key, nonce and vault_data
options in CLI when their value is always overwritten in forward().


I agree there is no need to expose them in CLI, but in this framework
the API also defines the CLI. If there's a way to keep them in the
server API but not expose them in the CLI please let me know. Or, if
there's a way to define completely separate server API (without a
matching client CLI) and client CLI (without a matching server API) that
will work too.


As I suggested above, you can split the commands into separate client
and server commands. The client command should inherit from
frontend.Local so that it is always executed locally and the server
command should have a NO_CLI = True attribute so that it is not
available in the CLI.


I see the vault_archive and vault_retrieve now inherit from PKQuery, and 
there is a hack to execute the forward() even on the server side. A few 
things below:


1. Why didn't you use frontend.Local as you initially suggested? If 
there's a problem with frontend.Local please attach the ticket number in 
the code.


2. The forward() can be merged into run(). There is no need to keep the 
code in forward(). It would make more sense to have a run() method that 
runs both on client and server, rather than a forward() that is supposed 
to run on the client only but now forced to run on server too, 
semantically speaking.



Attached is a patch including the requested changes.

I have also changed vault_config to vaultconfig_show, for consistency
with {,dns}config_show (it also makes the transport certificate
retrieval code in vault_{archive,retrieve} simpler).


3. The parameter description for nonce should be just 'Nonce' instead of 
'Nonce encrypted'.


4. There's a PEP8 error.

5. The VERSION needs to be updated.

Assuming the above issues are addressed, ACK.


I have noticed that triple-length DES is used for the session key.
Wouldn't AES be better?

 # generate session key
 mechanism = nss.CKM_DES3_CBC_PAD


That's the default used by the KRA's client library, and that's what the 
KRA has been tested with. We probably can change it to AES later. It 
shouldn't be blocking this patch.



BTW, ipa-kra-install is broken with pki-core-10.2.4-1, but it works with
pki-core-10.2.1-3.


There's a bug in IPA: https://bugzilla.redhat.com/show_bug.cgi?id=1228671

--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Jan Cholasta

Dne 2.6.2015 v 20:40 Simo Sorce napsal(a):

On Tue, 2015-06-02 at 07:07 -0500, Endi Sukma Dewata wrote:

On 6/2/2015 1:10 AM, Martin Kosek wrote:

Hi Endi,

Quickly skimming through your patches raised couple questions on my side:

1) Will it be possible to also store plain text password via Vault? It
talks about taking in the binary data or the text file, but will it also
work with plain user secrets (passwords)? I am talking about use like this:

# ipa vault-archive name --user mkosek --data Secret123


For security the plain text password should be stored in a file first:

# vi password.txt
# ipa vault-archive name --user mkosek --in password.txt

It's also possible to specify the password as base-64 encoded data:

# echo -n Secret123 | base64
# ipa vault-archive name --user mkosek --data U2VjcmV0MTIz

But it's not recommended since the data will be stored in the command
history and someone could see and decode it. I think passing a plain
text password as command line argument would be even worse. The --data
parameter is mainly used for unit testing.

Later we might be able to add an option to read from standard input:

# cat password.txt | ipa vault-archive name --user mkosek --std-in


Yes please, a way to pass in via stdin is extremely useful, as leaving
files on the filesystem is also a big risk.


This will not work well, it should use the normal prompting mechanism:

$ ipa vault-archive name --user user
Data: type data here

--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Martin Kosek
On 06/02/2015 11:22 PM, Alexander Bokovoy wrote:
 On Tue, 02 Jun 2015, Endi Sukma Dewata wrote:
 Please take a look at the new patch.

 On 6/2/2015 10:05 AM, Martin Kosek wrote:
 4) In the vault-archive forward method, you use pki module. However,
 this module will be only available on FreeIPA PKI-powered servers and
 not on FreeIPA clients - so this will not work unless freeipa-client
 gets a dependency on pki-base - which is definitely not something we
 want...

 In my opinion it should be fine to require pki-base on the client because 
 it
 contains just the client library, unless you have other concerns? Any
 objections to having pki-nss and pki-cryptography dependencies on the 
 client?

 Even if we can change the client code not to depend on pki module, since 
 in
 this framework the client and server code are written in the same plugin, 
 the
 import pki still cannot be removed since it's still needed by the server
 code, and I don't think conditional import is a good programming practice.

 I have major concerns here. Look at the different between installing
 freeipa-client and freeipa-client + pki-base on my F21:

 ~~
 $ sudo yum install freeipa-client
 ...
 Install  1 Package (+4 Dependent packages)

 Total download size: 2.6 M
 Installed size: 14 M
 ~~
 $ sudo yum install freeipa-client pki-base
 ...
 Install  2 Packages (+288 Dependent packages)

 Total download size: 160 M
 Installed size: 235 M
 ~~

 This is obviously a no-go for client. The conditional import is smaller 
 concern
 that big dependency growth on the client. We do them in trust plugin for
 example and it works fine (though I agree it is not ideal programming
 practice).

 IMO, we should limit new freeipa-client dependencies only to
 python-cryptography (or also python-nss in the worst case, in case
 python-cryptography is not enough) - there should be no pki dependencies at
 all, these should be only on the server side.

 OK. I opened a ticket to split the pki-base into separate Python and Java
 packages:
 https://fedorahosted.org/pki/ticket/1399

 For now in this patch I added conditional imports for pki.account and pki.key
 which are needed to access KRA on the server side. I removed dependency on
 pki.crypto on the client side and replaced it with direct python-nss code.

 On 6/2/2015 1:40 PM, Simo Sorce wrote:
 I have coded in python (jwcrypto)
 support for some key wrapping not yet available in python-cryptography
 and can lend you the code as needed.

 Thanks. I'll get back to you when it's time to add support for
 python-cryptography in KRA:
 https://fedorahosted.org/pki/ticket/1400

 On 6/2/2015 10:16 AM, Alexander Bokovoy wrote:
 Yes, please use conditional import here, it is perfectly valid use case
 for the client side.

 On 6/2/2015 1:40 PM, Simo Sorce wrote:
 conditional import is just fine

 The conditional imports that I've seen usually are used for importing
 different versions of the same module, which I think is acceptable because
 the dependency always exists. In the vault case we're selectively importing a
 module depending on where the code runs. I think that is bad because it adds
 complexity and it's easy to make mistakes. Any code that depends on that
 module would have to be (a) guarded:

  if pki_is_loaded:
  ... call pki ...

 or (b) used in a method that's only called if the module is loaded:

  def do_something(self): # runs only on server
  ... call pki ...

 The (a) is similar to #ifdef's which should be avoidable using OOD, and in
 (b) we may inadvertently call a wrong method indirectly. I think ideally the
 client and server code should be in separate files (so they can be deployed
 separately too), but the framework doesn't seem to allow that.
 This exactly the case we have to use here and we are using that in
 trusts case as well -- some code has to run on server only and shouldn't
 cause to install Samba related packages on the client. This is because
 IPA client is actually using the same IPA plugins that server uses, to
 have access to the API calls metadata and client-side callbacks are
 defined in the same place where server-side callbacks are. It is IPA
 framework design, so we have to use what we have.

This is planned to be changed BTW, when we start with the Thin Client concept
and have different code/plugins for FreeIPA server side and client side.

 In other words, it is not necessarily an evil under conditions we are
 dealing with.
 

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Martin Kosek
On 06/02/2015 08:34 PM, Simo Sorce wrote:
 On Tue, 2015-06-02 at 12:04 +0200, Jan Cholasta wrote:
 Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):
 On 5/28/2015 12:46 AM, Jan Cholasta wrote:
 On a related note, since KRA is optional, can we move the vaults
 container to cn=kra,cn=vaults? This is the convetion used by the other
 optional components (DNS and recently CA).

 I mean cn=vaults,cn=kra of course.

 If you are talking about the o=kra,PKI suffix, I'm not sure whether
 the IPA framework will work with it.

 If you are talking about adding a new cn=kra,IPA suffix entry on top
 of cn=vaults, what is the purpose of this entry? Is the entry going to
 be created/deleted automatically when the KRA is installed/removed? Is
 it going to be used for something else other than vaults?

 I'm talking about cn=kra,IPA suffix. It should be created only when 
 KRA is installed, although I think this can be done later after the 
 release, moving vaults to cn=kra should be good enough for now. It's 
 going to be used for everything KRA-specific.


 There are a lot of questions that need to be answered before we can make
 this change.

 This is about sticking to a convention, which everyone should do, and 
 everyone except KRA already does.

 I'm sorry I didn't realize this earlier, but the change must be done now.

 We probably should revisit this issue after the core vault
 functionality is added.


 We can't revisit it later because after release we are stuck with 
 whatever is there forever.

 See attachment for a patch which implements the change.

 
 Shouldn't we s/kra/vault/ ?
 After all the feature is called Vault, not KRA.

I thought we are naming it by the name of the optional subsystem, not the
feature itself. If for example, another feature from KRA is used, it would
still live in cn=kra, no?

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Alexander Bokovoy

On Wed, 03 Jun 2015, Endi Sukma Dewata wrote:

On 6/3/2015 1:41 AM, Martin Kosek wrote:

On 06/02/2015 11:22 PM, Alexander Bokovoy wrote:

On Tue, 02 Jun 2015, Endi Sukma Dewata wrote:

I think ideally the
client and server code should be in separate files (so they can be deployed
separately too), but the framework doesn't seem to allow that.



This exactly the case we have to use here and we are using that in
trusts case as well -- some code has to run on server only and shouldn't
cause to install Samba related packages on the client. This is because
IPA client is actually using the same IPA plugins that server uses, to
have access to the API calls metadata and client-side callbacks are
defined in the same place where server-side callbacks are. It is IPA
framework design, so we have to use what we have.


This is planned to be changed BTW, when we start with the Thin Client concept
and have different code/plugins for FreeIPA server side and client side.


Is there a ticket for this?


In other words, it is not necessarily an evil under conditions we are
dealing with.


Having to use the same plugins for client and server is a framework 
limitation/poor design. Having to use conditional imports to work 
around the limitation is a bad programming practice. The fact that 
trust plugin has to implement a similar workaround is not a 
justification, it just shows that the problem is not vault-specific.

There is another thing. Even when splitting client/server sides, we'll
need to check on the server side that certain functionality is
available. In trust case we have ID Views (a separate plugin) which does
use information about trusts to resolve users from AD to their
normalized references (SIDs) and few other places would be depending on
functionality only provided when Samba packages are installed.

To continue your approach, we would need to split also server-side parts
of plugins into separate callable units that would only be provided and
called when appropriate rpm subpackages are installed. This is unneeded
complication in place where we can simply handle dependencies in run
time and make sure the packaging deps are managed separately.
--
/ Alexander Bokovoy

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Endi Sukma Dewata

On 6/3/2015 8:52 AM, Alexander Bokovoy wrote:

Having to use the same plugins for client and server is a framework
limitation/poor design. Having to use conditional imports to work
around the limitation is a bad programming practice. The fact that
trust plugin has to implement a similar workaround is not a
justification, it just shows that the problem is not vault-specific.



There is another thing. Even when splitting client/server sides, we'll
need to check on the server side that certain functionality is
available. In trust case we have ID Views (a separate plugin) which does
use information about trusts to resolve users from AD to their
normalized references (SIDs) and few other places would be depending on
functionality only provided when Samba packages are installed.

To continue your approach, we would need to split also server-side parts
of plugins into separate callable units that would only be provided and
called when appropriate rpm subpackages are installed. This is unneeded
complication in place where we can simply handle dependencies in run
time and make sure the packaging deps are managed separately.


So there are two issues:
1. Conditional imports due to combined client and server plugin.
2. Conditional imports due to feature availability.

Issue #1 is generic and I think we pretty much agree that this is 
supposed to be fixed somehow.


Issue #2 is plugin-specific. I think there are different ways to solve 
this, some might be better than others. The solution that you pick will 
only affect that particular plugin and should not be generalized to 
other plugins or to justify #1.


In my opinion a code should have a fixed dependency, but some features 
can be enabled/disabled based on the configuration. Enabling a feature 
shouldn't be based on package installation because people might install 
a package for different reasons. So the code may look something like this:


  import module

  if feature is enabled:
  do something with the module

It shouldn't be like this:

  if package is installed:
  import module

  if package is installed:
  do something with the module

Of course this assumes that the package is lightweight enough to be 
installed regardless whether it will be used. I don't know if it's 
applicable to your case, but again, there are different ways to address 
issue #2.


--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Endi Sukma Dewata

On 6/3/2015 1:41 AM, Martin Kosek wrote:

On 06/02/2015 11:22 PM, Alexander Bokovoy wrote:

On Tue, 02 Jun 2015, Endi Sukma Dewata wrote:

I think ideally the
client and server code should be in separate files (so they can be deployed
separately too), but the framework doesn't seem to allow that.



This exactly the case we have to use here and we are using that in
trusts case as well -- some code has to run on server only and shouldn't
cause to install Samba related packages on the client. This is because
IPA client is actually using the same IPA plugins that server uses, to
have access to the API calls metadata and client-side callbacks are
defined in the same place where server-side callbacks are. It is IPA
framework design, so we have to use what we have.


This is planned to be changed BTW, when we start with the Thin Client concept
and have different code/plugins for FreeIPA server side and client side.


Is there a ticket for this?


In other words, it is not necessarily an evil under conditions we are
dealing with.


Having to use the same plugins for client and server is a framework 
limitation/poor design. Having to use conditional imports to work around 
the limitation is a bad programming practice. The fact that trust plugin 
has to implement a similar workaround is not a justification, it just 
shows that the problem is not vault-specific.


--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Endi Sukma Dewata

On 6/2/2015 1:34 PM, Simo Sorce wrote:

On Tue, 2015-06-02 at 12:04 +0200, Jan Cholasta wrote:

Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):

On 5/28/2015 12:46 AM, Jan Cholasta wrote:

On a related note, since KRA is optional, can we move the vaults
container to cn=kra,cn=vaults? This is the convetion used by the other
optional components (DNS and recently CA).


I mean cn=vaults,cn=kra of course.


If you are talking about the o=kra,PKI suffix, I'm not sure whether
the IPA framework will work with it.

If you are talking about adding a new cn=kra,IPA suffix entry on top
of cn=vaults, what is the purpose of this entry? Is the entry going to
be created/deleted automatically when the KRA is installed/removed? Is
it going to be used for something else other than vaults?


I'm talking about cn=kra,IPA suffix. It should be created only when
KRA is installed, although I think this can be done later after the
release, moving vaults to cn=kra should be good enough for now. It's
going to be used for everything KRA-specific.



There are a lot of questions that need to be answered before we can make
this change.


This is about sticking to a convention, which everyone should do, and
everyone except KRA already does.

I'm sorry I didn't realize this earlier, but the change must be done now.


We probably should revisit this issue after the core vault
functionality is added.



We can't revisit it later because after release we are stuck with
whatever is there forever.

See attachment for a patch which implements the change.



Shouldn't we s/kra/vault/ ?
After all the feature is called Vault, not KRA.

Simo.



Here are the options:
1. the original code uses cn=vaults,IPA suffix.
2. Honza proposed cn=vaults,cn=kra,IPA suffix, ACKed by Martin.

Are you proposing a third option cn=vaults,cn=vault,IPA suffix or 
did you mean the first option?


I think the first option would make more sense since we're not 
introducing KRA to the end user, but I'll let the IPA team decide. My 
next patch will be based on whatever pushed at the time.


--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Jan Cholasta

Dne 3.6.2015 v 14:58 Endi Sukma Dewata napsal(a):

On 6/2/2015 1:34 PM, Simo Sorce wrote:

On Tue, 2015-06-02 at 12:04 +0200, Jan Cholasta wrote:

Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):

On 5/28/2015 12:46 AM, Jan Cholasta wrote:

On a related note, since KRA is optional, can we move the vaults
container to cn=kra,cn=vaults? This is the convetion used by the
other
optional components (DNS and recently CA).


I mean cn=vaults,cn=kra of course.


If you are talking about the o=kra,PKI suffix, I'm not sure whether
the IPA framework will work with it.

If you are talking about adding a new cn=kra,IPA suffix entry on top
of cn=vaults, what is the purpose of this entry? Is the entry going to
be created/deleted automatically when the KRA is installed/removed? Is
it going to be used for something else other than vaults?


I'm talking about cn=kra,IPA suffix. It should be created only when
KRA is installed, although I think this can be done later after the
release, moving vaults to cn=kra should be good enough for now. It's
going to be used for everything KRA-specific.



There are a lot of questions that need to be answered before we can
make
this change.


This is about sticking to a convention, which everyone should do, and
everyone except KRA already does.

I'm sorry I didn't realize this earlier, but the change must be done
now.


We probably should revisit this issue after the core vault
functionality is added.



We can't revisit it later because after release we are stuck with
whatever is there forever.

See attachment for a patch which implements the change.



Shouldn't we s/kra/vault/ ?
After all the feature is called Vault, not KRA.

Simo.



Here are the options:
1. the original code uses cn=vaults,IPA suffix.
2. Honza proposed cn=vaults,cn=kra,IPA suffix, ACKed by Martin.

Are you proposing a third option cn=vaults,cn=vault,IPA suffix or
did you mean the first option?

I think the first option would make more sense since we're not
introducing KRA to the end user, but I'll let the IPA team decide. My
next patch will be based on whatever pushed at the time.


The DNs are not exposed to the end user, they are only relevant for our 
internal organization of entries.


--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Jan Cholasta

Dne 2.6.2015 v 02:00 Endi Sukma Dewata napsal(a):

Please take a look at the updated patch.

On 5/27/2015 12:39 AM, Jan Cholasta wrote:

21) vault_archive is not a retrieve operation, it should be
based on
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it
does
not do anything with LDAP. The same applies to vault_retrieve.


The vault_archive does not actually modify the LDAP entry because it
stores the data in KRA. It is actually an LDAPRetrieve operation
because
it needs to get the vault info before it can perform the archival
operation. Same thing with vault_retrieve.


It is not a LDAPRetrieve operation, because it has different
semantics.
Please use Command as base class and either use ldap2 for direct
LDAP or
call vault_show instead of hacking around LDAPRetrieve.


It's been changed to inherit from LDAPQuery instead.


NACK, it's not a LDAPQuery operation, because it has different
semantics. There is more to a command than executing code, so you
should
use a correct base class.


Changed to inherit from Command as requested. Now these commands no
longer have a direct access to the vault object (self.obj) although they
are accessing vault objects like other vault commands. Also now the
vault name argument has to be added explicitly on each command.


You can inherit from crud.Retrieve and crud.Update to get self.obj and
the argument back.


I tried this:

   class vault_retrieve(Command, crud.Retrieve):

and it gave me an error:

   TypeError: Error when calling the metaclass bases
   Cannot create a consistent method resolution
   order (MRO) for bases Retrieve, Command

I'm sticking with the original code since it works fine although not
ideal. I'm not a Python expert, so if you know how to fix this properly
please feel free to post a patch on top of this.


The class hierarchy is as follows:

   frontend.Command
   frontend.Method
   crud.PKQuery
   crud.Retrieve
   cdur.Update

So removing Command from the list of base classes should fix it.




If KRA is not installed, vault-archive and vault-retrieve fail with
internal error.


Added a code to check KRA installation in all vault commands. If you
know a way not to load the vault plugin if the KRA is not installed
please let me know, that's probably even better. Not sure how that will
work on the client side though.


I see this has been already resolved in the other thread.




The commands still behave differently based on whether they were called
from API which was initialized with in_server set to True or False.


That is unfortunately a restriction imposed by the framework. In order
to guarantee the security, the vault is designed to have separate client
and server code. The client code encrypts the secret, the server code
forwards the encrypted secret to KRA. To archive a secret into a vault
properly, you are supposed to call the client code. If you're calling
the server code directly, you are responsible to do your own encryption
(i.e. generating session key, nonce, and vault data).


I understand why the code has to be separated, what I don't understand 
is why it is in fact *not* separated and crammed into a single command, 
making weird and undefined behavior possible.




If another plugin wants to use vault, it should implement a client code
which calls the vault client code to perform the archival from the
client side.

What is the use case for calling the vault API from the server side
anyway? Wouldn't that defeat the purpose of having a vault? If a secret
exists on the server side in an unencrypted form doesn't it mean the
secret may already have been compromised?


Server API is used not only by the server itself, but also by installers 
for example. Anyway the point is that there *can't* be a broken API like 
this, you should at least raise an error if the command is called from 
server API, although actually separating it into client and server parts 
would be preferable.





There is no point in exposing the session_key, nonce and vault_data
options in CLI when their value is always overwritten in forward().


I agree there is no need to expose them in CLI, but in this framework
the API also defines the CLI. If there's a way to keep them in the
server API but not expose them in the CLI please let me know. Or, if
there's a way to define completely separate server API (without a
matching client CLI) and client CLI (without a matching server API) that
will work too.


As I suggested above, you can split the commands into separate client 
and server commands. The client command should inherit from 
frontend.Local so that it is always executed locally and the server 
command should have a NO_CLI = True attribute so that it is not 
available in the CLI.





Will this always succeed?

+# deactivate vault record in KRA
+response = kra_client.keys.list_keys(
+client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)


Yes. If there's no active keys it will 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Simo Sorce
On Wed, 2015-06-03 at 09:27 +0200, Martin Kosek wrote:
 On 06/02/2015 08:34 PM, Simo Sorce wrote:
  On Tue, 2015-06-02 at 12:04 +0200, Jan Cholasta wrote:
  Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):
  On 5/28/2015 12:46 AM, Jan Cholasta wrote:
  On a related note, since KRA is optional, can we move the vaults
  container to cn=kra,cn=vaults? This is the convetion used by the other
  optional components (DNS and recently CA).
 
  I mean cn=vaults,cn=kra of course.
 
  If you are talking about the o=kra,PKI suffix, I'm not sure whether
  the IPA framework will work with it.
 
  If you are talking about adding a new cn=kra,IPA suffix entry on top
  of cn=vaults, what is the purpose of this entry? Is the entry going to
  be created/deleted automatically when the KRA is installed/removed? Is
  it going to be used for something else other than vaults?
 
  I'm talking about cn=kra,IPA suffix. It should be created only when 
  KRA is installed, although I think this can be done later after the 
  release, moving vaults to cn=kra should be good enough for now. It's 
  going to be used for everything KRA-specific.
 
 
  There are a lot of questions that need to be answered before we can make
  this change.
 
  This is about sticking to a convention, which everyone should do, and 
  everyone except KRA already does.
 
  I'm sorry I didn't realize this earlier, but the change must be done now.
 
  We probably should revisit this issue after the core vault
  functionality is added.
 
 
  We can't revisit it later because after release we are stuck with 
  whatever is there forever.
 
  See attachment for a patch which implements the change.
 
  
  Shouldn't we s/kra/vault/ ?
  After all the feature is called Vault, not KRA.
 
 I thought we are naming it by the name of the optional subsystem, not the
 feature itself. If for example, another feature from KRA is used, it would
 still live in cn=kra, no?

For services so far we have CA, not dogtag, and LDAP, not 389ds, also
KDC not krb5kdc and kpasswd not kadmind, etc... we normally named
everything after the function. Now kra is probably a somewhat generic
term, but I have not been able to find what it means exactly in 5
minutes, and it is quite obscure as a name. OTOH cn=Vault would make it
really clear what's in it. I do not have a very strong opinion but a
generic and clear name is important for the DIT.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-03 Thread Jan Cholasta

Dne 3.6.2015 v 15:20 Simo Sorce napsal(a):

On Wed, 2015-06-03 at 09:27 +0200, Martin Kosek wrote:

On 06/02/2015 08:34 PM, Simo Sorce wrote:

On Tue, 2015-06-02 at 12:04 +0200, Jan Cholasta wrote:

Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):

On 5/28/2015 12:46 AM, Jan Cholasta wrote:

On a related note, since KRA is optional, can we move the vaults
container to cn=kra,cn=vaults? This is the convetion used by the other
optional components (DNS and recently CA).


I mean cn=vaults,cn=kra of course.


If you are talking about the o=kra,PKI suffix, I'm not sure whether
the IPA framework will work with it.

If you are talking about adding a new cn=kra,IPA suffix entry on top
of cn=vaults, what is the purpose of this entry? Is the entry going to
be created/deleted automatically when the KRA is installed/removed? Is
it going to be used for something else other than vaults?


I'm talking about cn=kra,IPA suffix. It should be created only when
KRA is installed, although I think this can be done later after the
release, moving vaults to cn=kra should be good enough for now. It's
going to be used for everything KRA-specific.



There are a lot of questions that need to be answered before we can make
this change.


This is about sticking to a convention, which everyone should do, and
everyone except KRA already does.

I'm sorry I didn't realize this earlier, but the change must be done now.


We probably should revisit this issue after the core vault
functionality is added.



We can't revisit it later because after release we are stuck with
whatever is there forever.

See attachment for a patch which implements the change.



Shouldn't we s/kra/vault/ ?
After all the feature is called Vault, not KRA.


I thought we are naming it by the name of the optional subsystem, not the
feature itself. If for example, another feature from KRA is used, it would
still live in cn=kra, no?


For services so far we have CA, not dogtag, and LDAP, not 389ds, also
KDC not krb5kdc and kpasswd not kadmind, etc... we normally named
everything after the function. Now kra is probably a somewhat generic
term, but I have not been able to find what it means exactly in 5
minutes, and it is quite obscure as a name. OTOH cn=Vault would make it
really clear what's in it. I do not have a very strong opinion but a
generic and clear name is important for the DIT.


There is also ipa-kra-install and I guess 
cn=KRA,cn=fqdn,cn=masters,cn=ipa,cn=etc. If we rename it, it should be 
renamed everywhere, and I'm not sure if that's worth it.


Also vault is too generic, it should be password vault, but that's 
too long, so IMO KRA is better, as it's short and descriptive.


Are vaults the only feature KRA provides? If there are more possible 
features provided by KRA, it's another reason to keep it KRA.


--
Jan Cholasta

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Simo Sorce
On Tue, 2015-06-02 at 07:07 -0500, Endi Sukma Dewata wrote:
 On 6/2/2015 1:10 AM, Martin Kosek wrote:
  Hi Endi,
 
  Quickly skimming through your patches raised couple questions on my side:
 
  1) Will it be possible to also store plain text password via Vault? It
  talks about taking in the binary data or the text file, but will it also
  work with plain user secrets (passwords)? I am talking about use like this:
 
  # ipa vault-archive name --user mkosek --data Secret123
 
 For security the plain text password should be stored in a file first:
 
# vi password.txt
# ipa vault-archive name --user mkosek --in password.txt
 
 It's also possible to specify the password as base-64 encoded data:
 
# echo -n Secret123 | base64
# ipa vault-archive name --user mkosek --data U2VjcmV0MTIz
 
 But it's not recommended since the data will be stored in the command 
 history and someone could see and decode it. I think passing a plain 
 text password as command line argument would be even worse. The --data 
 parameter is mainly used for unit testing.
 
 Later we might be able to add an option to read from standard input:
 
# cat password.txt | ipa vault-archive name --user mkosek --std-in

Yes please, a way to pass in via stdin is extremely useful, as leaving
files on the filesystem is also a big risk.

  2) Didn't we discuss a dependency of IPA/Vault on python-cryptography in
  the past? I rather see use of python-nss for cryptography...
 
 Yes. I might have mentioned that it would be in the 2nd (current) vault 
 patch. Actually it will be in the 3rd patch when we add the symmetric 
 and asymmetric vaults. The symmetric and asymmetric encryption will be 
 implemented using python-cryptography. You can also see this in an old 
 patch (#358) but it's obsolete now.
 
 The standard vault in the current patch uses python-nss for transport 
 encryption because when the KRA interface was written 
 python-cryptography wasn't available on Fedora, it didn't support 
 certificates, and I'm not sure if it supports key wrapping.

It depends on the key wrapping, I have coded in python (jwcrypto)
support for some key wrapping not yet available in python-cryptography
and can lend you the code as needed.

 The symmetric and asymmetric vaults add an additional layer of 
 encryption on top of the standard transport encryption, so it will 
 depend on both python-nss and python-cryptography.
 
 In the future if the KRA can support python-cryptography without 
 python-nss we may be able to drop the python-nss dependency from vaults.
 
  3) You do a lot of actions in the forward() method (as planned in
  https://www.freeipa.org/page/V4/Password_Vault#Archival). But how do you
  envision that this is consumed by the Web UI? It does not have access to
  the forward() method. Would it need to also include some crypto library?
 
 If Web UI wants to access vault (not sure if everybody agrees with 
 that), it would have to perform an encryption on the browser side. In 
 that case we will need to use either WebCrypto or a browser-specific 
 extension to implement something similar to vault_archive.forward(), 
 assuming the required cryptographic functionalities are available. In 
 the future PKI might be able to provide a JavaScript interface for KRA.

I so much want to NACK crypto in web browsers ... but we may have to do
it, it stinks soo much though ... Perhaps a plugin ?

  4) In the vault-archive forward method, you use pki module. However,
  this module will be only available on FreeIPA PKI-powered servers and
  not on FreeIPA clients - so this will not work unless freeipa-client
  gets a dependency on pki-base - which is definitely not something we
  want...
 
 In my opinion it should be fine to require pki-base on the client 

NACK look at the dependency chain for that packages.

 because it contains just the client library, unless you have other 
 concerns? Any objections to having pki-nss and pki-cryptography 
 dependencies on the client?

you mean python-nss/python-cryptography ? I see no problem having them
as dependencies on the client.

 Even if we can change the client code not to depend on pki module, 
 since in this framework the client and server code are written in the 
 same plugin, the import pki still cannot be removed since it's still 
 needed by the server code, and I don't think conditional import is a 
 good programming practice.

conditional import is just fine

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Simo Sorce
On Tue, 2015-06-02 at 12:04 +0200, Jan Cholasta wrote:
 Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):
  On 5/28/2015 12:46 AM, Jan Cholasta wrote:
  On a related note, since KRA is optional, can we move the vaults
  container to cn=kra,cn=vaults? This is the convetion used by the other
  optional components (DNS and recently CA).
 
  I mean cn=vaults,cn=kra of course.
 
  If you are talking about the o=kra,PKI suffix, I'm not sure whether
  the IPA framework will work with it.
 
  If you are talking about adding a new cn=kra,IPA suffix entry on top
  of cn=vaults, what is the purpose of this entry? Is the entry going to
  be created/deleted automatically when the KRA is installed/removed? Is
  it going to be used for something else other than vaults?
 
 I'm talking about cn=kra,IPA suffix. It should be created only when 
 KRA is installed, although I think this can be done later after the 
 release, moving vaults to cn=kra should be good enough for now. It's 
 going to be used for everything KRA-specific.
 
 
  There are a lot of questions that need to be answered before we can make
  this change.
 
 This is about sticking to a convention, which everyone should do, and 
 everyone except KRA already does.
 
 I'm sorry I didn't realize this earlier, but the change must be done now.
 
  We probably should revisit this issue after the core vault
  functionality is added.
 
 
 We can't revisit it later because after release we are stuck with 
 whatever is there forever.
 
 See attachment for a patch which implements the change.
 

Shouldn't we s/kra/vault/ ?
After all the feature is called Vault, not KRA.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Endi Sukma Dewata

Please take a look at the new patch.

On 6/2/2015 10:05 AM, Martin Kosek wrote:

4) In the vault-archive forward method, you use pki module. However,
this module will be only available on FreeIPA PKI-powered servers and
not on FreeIPA clients - so this will not work unless freeipa-client
gets a dependency on pki-base - which is definitely not something we
want...


In my opinion it should be fine to require pki-base on the client because it
contains just the client library, unless you have other concerns? Any
objections to having pki-nss and pki-cryptography dependencies on the client?

Even if we can change the client code not to depend on pki module, since in
this framework the client and server code are written in the same plugin, the
import pki still cannot be removed since it's still needed by the server
code, and I don't think conditional import is a good programming practice.


I have major concerns here. Look at the different between installing
freeipa-client and freeipa-client + pki-base on my F21:

~~
$ sudo yum install freeipa-client
...
Install  1 Package (+4 Dependent packages)

Total download size: 2.6 M
Installed size: 14 M
~~
$ sudo yum install freeipa-client pki-base
...
Install  2 Packages (+288 Dependent packages)

Total download size: 160 M
Installed size: 235 M
~~

This is obviously a no-go for client. The conditional import is smaller concern
that big dependency growth on the client. We do them in trust plugin for
example and it works fine (though I agree it is not ideal programming practice).

IMO, we should limit new freeipa-client dependencies only to
python-cryptography (or also python-nss in the worst case, in case
python-cryptography is not enough) - there should be no pki dependencies at
all, these should be only on the server side.


OK. I opened a ticket to split the pki-base into separate Python and 
Java packages:

https://fedorahosted.org/pki/ticket/1399

For now in this patch I added conditional imports for pki.account and 
pki.key which are needed to access KRA on the server side. I removed 
dependency on pki.crypto on the client side and replaced it with direct 
python-nss code.


On 6/2/2015 1:40 PM, Simo Sorce wrote:
 I have coded in python (jwcrypto)
 support for some key wrapping not yet available in python-cryptography
 and can lend you the code as needed.

Thanks. I'll get back to you when it's time to add support for 
python-cryptography in KRA:

https://fedorahosted.org/pki/ticket/1400

On 6/2/2015 10:16 AM, Alexander Bokovoy wrote:

Yes, please use conditional import here, it is perfectly valid use case
for the client side.


On 6/2/2015 1:40 PM, Simo Sorce wrote:
 conditional import is just fine

The conditional imports that I've seen usually are used for importing 
different versions of the same module, which I think is acceptable 
because the dependency always exists. In the vault case we're 
selectively importing a module depending on where the code runs. I think 
that is bad because it adds complexity and it's easy to make mistakes. 
Any code that depends on that module would have to be (a) guarded:


  if pki_is_loaded:
  ... call pki ...

or (b) used in a method that's only called if the module is loaded:

  def do_something(self): # runs only on server
  ... call pki ...

The (a) is similar to #ifdef's which should be avoidable using OOD, and 
in (b) we may inadvertently call a wrong method indirectly. I think 
ideally the client and server code should be in separate files (so they 
can be deployed separately too), but the framework doesn't seem to allow 
that.


Regardless, the conditional imports are in.

--
Endi S. Dewata
From 0e9d3868423c21dc47d125f4b3c23e8261c4655f Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Tue, 21 Oct 2014 10:57:08 -0400
Subject: [PATCH] Added vault-archive and vault-retrieve commands.

New commands have been added to archive and retrieve
data into and from a vault, also to retrieve the
transport certificate.

https://fedorahosted.org/freeipa/ticket/3872
---
 API.txt   |  28 ++
 VERSION   |   4 +-
 ipalib/plugins/vault.py   | 517 +-
 ipatests/test_xmlrpc/test_vault_plugin.py |  71 +++-
 4 files changed, 616 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index 
da69f32de5c12c0d85a7d61d9027385aa3c0ee05..3741e6f16689e43838c2d31a44872d1ea47589c7
 100644
--- a/API.txt
+++ b/API.txt
@@ -4768,6 +4768,24 @@ option: Str('version?', exclude='webui')
 output: Entry('result', type 'dict', Gettext('A dictionary representing an 
LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
+command: vault_archive
+args: 1,9,1
+arg: Str('cn', cli_name='name', 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Alexander Bokovoy

On Tue, 02 Jun 2015, Endi Sukma Dewata wrote:

Please take a look at the new patch.

On 6/2/2015 10:05 AM, Martin Kosek wrote:

4) In the vault-archive forward method, you use pki module. However,
this module will be only available on FreeIPA PKI-powered servers and
not on FreeIPA clients - so this will not work unless freeipa-client
gets a dependency on pki-base - which is definitely not something we
want...


In my opinion it should be fine to require pki-base on the client because it
contains just the client library, unless you have other concerns? Any
objections to having pki-nss and pki-cryptography dependencies on the client?

Even if we can change the client code not to depend on pki module, since in
this framework the client and server code are written in the same plugin, the
import pki still cannot be removed since it's still needed by the server
code, and I don't think conditional import is a good programming practice.


I have major concerns here. Look at the different between installing
freeipa-client and freeipa-client + pki-base on my F21:

~~
$ sudo yum install freeipa-client
...
Install  1 Package (+4 Dependent packages)

Total download size: 2.6 M
Installed size: 14 M
~~
$ sudo yum install freeipa-client pki-base
...
Install  2 Packages (+288 Dependent packages)

Total download size: 160 M
Installed size: 235 M
~~

This is obviously a no-go for client. The conditional import is smaller concern
that big dependency growth on the client. We do them in trust plugin for
example and it works fine (though I agree it is not ideal programming practice).

IMO, we should limit new freeipa-client dependencies only to
python-cryptography (or also python-nss in the worst case, in case
python-cryptography is not enough) - there should be no pki dependencies at
all, these should be only on the server side.


OK. I opened a ticket to split the pki-base into separate Python and 
Java packages:

https://fedorahosted.org/pki/ticket/1399

For now in this patch I added conditional imports for pki.account and 
pki.key which are needed to access KRA on the server side. I removed 
dependency on pki.crypto on the client side and replaced it with 
direct python-nss code.


On 6/2/2015 1:40 PM, Simo Sorce wrote:

I have coded in python (jwcrypto)
support for some key wrapping not yet available in python-cryptography
and can lend you the code as needed.


Thanks. I'll get back to you when it's time to add support for 
python-cryptography in KRA:

https://fedorahosted.org/pki/ticket/1400

On 6/2/2015 10:16 AM, Alexander Bokovoy wrote:

Yes, please use conditional import here, it is perfectly valid use case
for the client side.


On 6/2/2015 1:40 PM, Simo Sorce wrote:

conditional import is just fine


The conditional imports that I've seen usually are used for importing 
different versions of the same module, which I think is acceptable 
because the dependency always exists. In the vault case we're 
selectively importing a module depending on where the code runs. I 
think that is bad because it adds complexity and it's easy to make 
mistakes. Any code that depends on that module would have to be (a) 
guarded:


 if pki_is_loaded:
 ... call pki ...

or (b) used in a method that's only called if the module is loaded:

 def do_something(self): # runs only on server
 ... call pki ...

The (a) is similar to #ifdef's which should be avoidable using OOD, 
and in (b) we may inadvertently call a wrong method indirectly. I 
think ideally the client and server code should be in separate files 
(so they can be deployed separately too), but the framework doesn't 
seem to allow that.

This exactly the case we have to use here and we are using that in
trusts case as well -- some code has to run on server only and shouldn't
cause to install Samba related packages on the client. This is because
IPA client is actually using the same IPA plugins that server uses, to
have access to the API calls metadata and client-side callbacks are
defined in the same place where server-side callbacks are. It is IPA
framework design, so we have to use what we have.

In other words, it is not necessarily an evil under conditions we are
dealing with.

--
/ Alexander Bokovoy

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Martin Kosek
On 06/02/2015 12:04 PM, Jan Cholasta wrote:
 Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):
 On 5/28/2015 12:46 AM, Jan Cholasta wrote:
 On a related note, since KRA is optional, can we move the vaults
 container to cn=kra,cn=vaults? This is the convetion used by the other
 optional components (DNS and recently CA).

 I mean cn=vaults,cn=kra of course.

 If you are talking about the o=kra,PKI suffix, I'm not sure whether
 the IPA framework will work with it.

 If you are talking about adding a new cn=kra,IPA suffix entry on top
 of cn=vaults, what is the purpose of this entry? Is the entry going to
 be created/deleted automatically when the KRA is installed/removed? Is
 it going to be used for something else other than vaults?
 
 I'm talking about cn=kra,IPA suffix. It should be created only when KRA is
 installed, although I think this can be done later after the release, moving
 vaults to cn=kra should be good enough for now. It's going to be used for
 everything KRA-specific.
 

 There are a lot of questions that need to be answered before we can make
 this change.
 
 This is about sticking to a convention, which everyone should do, and everyone
 except KRA already does.
 
 I'm sorry I didn't realize this earlier, but the change must be done now.

+1 for this change. I do not even think it will that big deal, it is just about
the default space in the IPA tree - to have proper structure in it (DNS has
cn=dns, KRA has cn=kra, etc.).

 
 We probably should revisit this issue after the core vault
 functionality is added.

 
 We can't revisit it later because after release we are stuck with whatever is
 there forever.

Right.

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Endi Sukma Dewata

On 6/2/2015 1:10 AM, Martin Kosek wrote:

Hi Endi,

Quickly skimming through your patches raised couple questions on my side:

1) Will it be possible to also store plain text password via Vault? It
talks about taking in the binary data or the text file, but will it also
work with plain user secrets (passwords)? I am talking about use like this:

# ipa vault-archive name --user mkosek --data Secret123


For security the plain text password should be stored in a file first:

  # vi password.txt
  # ipa vault-archive name --user mkosek --in password.txt

It's also possible to specify the password as base-64 encoded data:

  # echo -n Secret123 | base64
  # ipa vault-archive name --user mkosek --data U2VjcmV0MTIz

But it's not recommended since the data will be stored in the command 
history and someone could see and decode it. I think passing a plain 
text password as command line argument would be even worse. The --data 
parameter is mainly used for unit testing.


Later we might be able to add an option to read from standard input:

  # cat password.txt | ipa vault-archive name --user mkosek --std-in


2) Didn't we discuss a dependency of IPA/Vault on python-cryptography in
the past? I rather see use of python-nss for cryptography...


Yes. I might have mentioned that it would be in the 2nd (current) vault 
patch. Actually it will be in the 3rd patch when we add the symmetric 
and asymmetric vaults. The symmetric and asymmetric encryption will be 
implemented using python-cryptography. You can also see this in an old 
patch (#358) but it's obsolete now.


The standard vault in the current patch uses python-nss for transport 
encryption because when the KRA interface was written 
python-cryptography wasn't available on Fedora, it didn't support 
certificates, and I'm not sure if it supports key wrapping.


The symmetric and asymmetric vaults add an additional layer of 
encryption on top of the standard transport encryption, so it will 
depend on both python-nss and python-cryptography.


In the future if the KRA can support python-cryptography without 
python-nss we may be able to drop the python-nss dependency from vaults.



3) You do a lot of actions in the forward() method (as planned in
https://www.freeipa.org/page/V4/Password_Vault#Archival). But how do you
envision that this is consumed by the Web UI? It does not have access to
the forward() method. Would it need to also include some crypto library?


If Web UI wants to access vault (not sure if everybody agrees with 
that), it would have to perform an encryption on the browser side. In 
that case we will need to use either WebCrypto or a browser-specific 
extension to implement something similar to vault_archive.forward(), 
assuming the required cryptographic functionalities are available. In 
the future PKI might be able to provide a JavaScript interface for KRA.



4) In the vault-archive forward method, you use pki module. However,
this module will be only available on FreeIPA PKI-powered servers and
not on FreeIPA clients - so this will not work unless freeipa-client
gets a dependency on pki-base - which is definitely not something we
want...


In my opinion it should be fine to require pki-base on the client 
because it contains just the client library, unless you have other 
concerns? Any objections to having pki-nss and pki-cryptography 
dependencies on the client?


Even if we can change the client code not to depend on pki module, 
since in this framework the client and server code are written in the 
same plugin, the import pki still cannot be removed since it's still 
needed by the server code, and I don't think conditional import is a 
good programming practice.



Thanks,
Martin


--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Jan Cholasta

Dne 2.6.2015 v 02:02 Endi Sukma Dewata napsal(a):

On 5/28/2015 12:46 AM, Jan Cholasta wrote:

On a related note, since KRA is optional, can we move the vaults
container to cn=kra,cn=vaults? This is the convetion used by the other
optional components (DNS and recently CA).


I mean cn=vaults,cn=kra of course.


If you are talking about the o=kra,PKI suffix, I'm not sure whether
the IPA framework will work with it.

If you are talking about adding a new cn=kra,IPA suffix entry on top
of cn=vaults, what is the purpose of this entry? Is the entry going to
be created/deleted automatically when the KRA is installed/removed? Is
it going to be used for something else other than vaults?


I'm talking about cn=kra,IPA suffix. It should be created only when 
KRA is installed, although I think this can be done later after the 
release, moving vaults to cn=kra should be good enough for now. It's 
going to be used for everything KRA-specific.




There are a lot of questions that need to be answered before we can make
this change.


This is about sticking to a convention, which everyone should do, and 
everyone except KRA already does.


I'm sorry I didn't realize this earlier, but the change must be done now.


We probably should revisit this issue after the core vault
functionality is added.



We can't revisit it later because after release we are stuck with 
whatever is there forever.


See attachment for a patch which implements the change.

--
Jan Cholasta
From 47295de5fb63195f7c07fa2528c6d6450e25d659 Mon Sep 17 00:00:00 2001
From: Jan Cholasta jchol...@redhat.com
Date: Tue, 2 Jun 2015 09:40:50 +
Subject: [PATCH] vault: Move vaults to cn=vaults,cn=kra

https://fedorahosted.org/freeipa/ticket/3872
---
 install/updates/40-vault.update   | 13 +
 ipa-client/man/default.conf.5 |  2 +-
 ipalib/constants.py   |  2 +-
 ipatests/test_xmlrpc/test_vault_plugin.py | 24 
 4 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/install/updates/40-vault.update b/install/updates/40-vault.update
index 5a6b8c6..dcd1e2a 100644
--- a/install/updates/40-vault.update
+++ b/install/updates/40-vault.update
@@ -1,19 +1,24 @@
-dn: cn=vaults,$SUFFIX
+dn: cn=kra,$SUFFIX
+default: objectClass: top
+default: objectClass: nsContainer
+default: cn: kra
+
+dn: cn=vaults,cn=kra,$SUFFIX
 default: objectClass: top
 default: objectClass: nsContainer
 default: cn: vaults
 
-dn: cn=services,cn=vaults,$SUFFIX
+dn: cn=services,cn=vaults,cn=kra,$SUFFIX
 default: objectClass: top
 default: objectClass: nsContainer
 default: cn: services
 
-dn: cn=shared,cn=vaults,$SUFFIX
+dn: cn=shared,cn=vaults,cn=kra,$SUFFIX
 default: objectClass: top
 default: objectClass: nsContainer
 default: cn: shared
 
-dn: cn=users,cn=vaults,$SUFFIX
+dn: cn=users,cn=vaults,cn=kra,$SUFFIX
 default: objectClass: top
 default: objectClass: nsContainer
 default: cn: users
diff --git a/ipa-client/man/default.conf.5 b/ipa-client/man/default.conf.5
index 0973f1a..e345e93 100644
--- a/ipa-client/man/default.conf.5
+++ b/ipa-client/man/default.conf.5
@@ -221,7 +221,7 @@ The following define the containers for the IPA server. Containers define where
   container_sudocmdgroup: cn=sudocmdgroups,cn=sudo
   container_sudorule: cn=sudorules,cn=sudo
   container_user: cn=users,cn=accounts
-  container_vault: cn=vaults
+  container_vault: cn=vaults,cn=kra
   container_virtual: cn=virtual operations,cn=etc
 
 .SH FILES
diff --git a/ipalib/constants.py b/ipalib/constants.py
index 95dec54..7815e14 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -99,7 +99,7 @@ DEFAULT_CONFIG = (
 ('container_hbacservice', DN(('cn', 'hbacservices'), ('cn', 'hbac'))),
 ('container_hbacservicegroup', DN(('cn', 'hbacservicegroups'), ('cn', 'hbac'))),
 ('container_dns', DN(('cn', 'dns'))),
-('container_vault', DN(('cn', 'vaults'))),
+('container_vault', DN(('cn', 'vaults'), ('cn', 'kra'))),
 ('container_virtual', DN(('cn', 'virtual operations'), ('cn', 'etc'))),
 ('container_sudorule', DN(('cn', 'sudorules'), ('cn', 'sudo'))),
 ('container_sudocmd', DN(('cn', 'sudocmds'), ('cn', 'sudo'))),
diff --git a/ipatests/test_xmlrpc/test_vault_plugin.py b/ipatests/test_xmlrpc/test_vault_plugin.py
index 44d397c..012baec 100644
--- a/ipatests/test_xmlrpc/test_vault_plugin.py
+++ b/ipatests/test_xmlrpc/test_vault_plugin.py
@@ -54,7 +54,7 @@ class test_vault_plugin(Declarative):
 'value': vault_name,
 'summary': 'Added vault %s' % vault_name,
 'result': {
-'dn': u'cn=%s,cn=admin,cn=users,cn=vaults,%s'
+'dn': u'cn=%s,cn=admin,cn=users,cn=vaults,cn=kra,%s'
   % (vault_name, api.env.basedn),
 'objectclass': [u'top', u'ipaVault'],
 'cn': [vault_name],
@@ -75,7 +75,7 @@ class test_vault_plugin(Declarative):
 'summary': u'1 vault matched',
   

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Martin Kosek
On 06/02/2015 02:07 PM, Endi Sukma Dewata wrote:
 On 6/2/2015 1:10 AM, Martin Kosek wrote:
 Hi Endi,

 Quickly skimming through your patches raised couple questions on my side:

 1) Will it be possible to also store plain text password via Vault? It
 talks about taking in the binary data or the text file, but will it also
 work with plain user secrets (passwords)? I am talking about use like this:

 # ipa vault-archive name --user mkosek --data Secret123
 
 For security the plain text password should be stored in a file first:
 
   # vi password.txt
   # ipa vault-archive name --user mkosek --in password.txt
 
 It's also possible to specify the password as base-64 encoded data:
 
   # echo -n Secret123 | base64
   # ipa vault-archive name --user mkosek --data U2VjcmV0MTIz
 
 But it's not recommended since the data will be stored in the command history
 and someone could see and decode it. I think passing a plain text password as
 command line argument would be even worse. The --data parameter is mainly used
 for unit testing.
 
 Later we might be able to add an option to read from standard input:
 
   # cat password.txt | ipa vault-archive name --user mkosek --std-in

Ok. Well, base64 + file input look as good enough for now. I was mostly
concerned about usability of the solution for normal users as for a manual
secret, it is not convenient to always create an interim file.

We will see based on user experience, maybe Web UI or further CLI-only
additions will be the answer.

 2) Didn't we discuss a dependency of IPA/Vault on python-cryptography in
 the past? I rather see use of python-nss for cryptography...
 
 Yes. I might have mentioned that it would be in the 2nd (current) vault patch.
 Actually it will be in the 3rd patch when we add the symmetric and asymmetric
 vaults. The symmetric and asymmetric encryption will be implemented using
 python-cryptography. You can also see this in an old patch (#358) but it's
 obsolete now.

Ok.

 The standard vault in the current patch uses python-nss for transport
 encryption because when the KRA interface was written python-cryptography
 wasn't available on Fedora, it didn't support certificates, and I'm not sure 
 if
 it supports key wrapping.
 
 The symmetric and asymmetric vaults add an additional layer of encryption on
 top of the standard transport encryption, so it will depend on both python-nss
 and python-cryptography.
 
 In the future if the KRA can support python-cryptography without python-nss we
 may be able to drop the python-nss dependency from vaults.

Ok.

 
 3) You do a lot of actions in the forward() method (as planned in
 https://www.freeipa.org/page/V4/Password_Vault#Archival). But how do you
 envision that this is consumed by the Web UI? It does not have access to
 the forward() method. Would it need to also include some crypto library?
 
 If Web UI wants to access vault (not sure if everybody agrees with that), it
 would have to perform an encryption on the browser side. In that case we will
 need to use either WebCrypto or a browser-specific extension to implement
 something similar to vault_archive.forward(), assuming the required
 cryptographic functionalities are available. In the future PKI might be able 
 to
 provide a JavaScript interface for KRA.

Ok, makes sense. I think we will want Web UI at some point, but the summary for
FreeIPA 4.2 seems - no Web UI for Vault (yet).

 4) In the vault-archive forward method, you use pki module. However,
 this module will be only available on FreeIPA PKI-powered servers and
 not on FreeIPA clients - so this will not work unless freeipa-client
 gets a dependency on pki-base - which is definitely not something we
 want...
 
 In my opinion it should be fine to require pki-base on the client because it
 contains just the client library, unless you have other concerns? Any
 objections to having pki-nss and pki-cryptography dependencies on the client?
 
 Even if we can change the client code not to depend on pki module, since in
 this framework the client and server code are written in the same plugin, the
 import pki still cannot be removed since it's still needed by the server
 code, and I don't think conditional import is a good programming practice.

I have major concerns here. Look at the different between installing
freeipa-client and freeipa-client + pki-base on my F21:

~~
$ sudo yum install freeipa-client
...
Install  1 Package (+4 Dependent packages)

Total download size: 2.6 M
Installed size: 14 M
~~
$ sudo yum install freeipa-client pki-base
...
Install  2 Packages (+288 Dependent packages)

Total download size: 160 M
Installed size: 235 M
~~

This is obviously a no-go for client. The conditional import is smaller concern
that big dependency growth on the client. We do them in trust plugin for
example and it works fine (though I agree it is not ideal programming 

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Alexander Bokovoy

On Tue, 02 Jun 2015, Martin Kosek wrote:

But it's not recommended since the data will be stored in the command history
and someone could see and decode it. I think passing a plain text password as
command line argument would be even worse. The --data parameter is mainly used
for unit testing.

Later we might be able to add an option to read from standard input:

  # cat password.txt | ipa vault-archive name --user mkosek --std-in


Ok. Well, base64 + file input look as good enough for now. I was mostly
concerned about usability of the solution for normal users as for a manual
secret, it is not convenient to always create an interim file.

We will see based on user experience, maybe Web UI or further CLI-only
additions will be the answer.

Correct, this is a part that can and should be driven by actual use
experience. Reading from the stdin is easy to implement (we have it done
for password already) so maybe we can simply reuse password option here
for such case, we even have a flag for omitting the confirmation prompt.
This is fairly small addition.


4) In the vault-archive forward method, you use pki module. However,
this module will be only available on FreeIPA PKI-powered servers and
not on FreeIPA clients - so this will not work unless freeipa-client
gets a dependency on pki-base - which is definitely not something we
want...


In my opinion it should be fine to require pki-base on the client because it
contains just the client library, unless you have other concerns? Any
objections to having pki-nss and pki-cryptography dependencies on the client?

Even if we can change the client code not to depend on pki module, since in
this framework the client and server code are written in the same plugin, the
import pki still cannot be removed since it's still needed by the server
code, and I don't think conditional import is a good programming practice.


I have major concerns here. Look at the different between installing
freeipa-client and freeipa-client + pki-base on my F21:

~~
$ sudo yum install freeipa-client
...
Install  1 Package (+4 Dependent packages)

Total download size: 2.6 M
Installed size: 14 M
~~
$ sudo yum install freeipa-client pki-base
...
Install  2 Packages (+288 Dependent packages)

Total download size: 160 M
Installed size: 235 M
~~

This is obviously a no-go for client. The conditional import is smaller concern
that big dependency growth on the client. We do them in trust plugin for
example and it works fine (though I agree it is not ideal programming practice).

IMO, we should limit new freeipa-client dependencies only to
python-cryptography (or also python-nss in the worst case, in case
python-cryptography is not enough) - there should be no pki dependencies at
all, these should be only on the server side.

Yes, please use conditional import here, it is perfectly valid use case
for the client side.
--
/ Alexander Bokovoy

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-02 Thread Martin Kosek

On 06/02/2015 02:00 AM, Endi Sukma Dewata wrote:

Please take a look at the updated patch.

On 5/27/2015 12:39 AM, Jan Cholasta wrote:

21) vault_archive is not a retrieve operation, it should be based on
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it
does
not do anything with LDAP. The same applies to vault_retrieve.


The vault_archive does not actually modify the LDAP entry because it
stores the data in KRA. It is actually an LDAPRetrieve operation
because
it needs to get the vault info before it can perform the archival
operation. Same thing with vault_retrieve.


It is not a LDAPRetrieve operation, because it has different
semantics.
Please use Command as base class and either use ldap2 for direct
LDAP or
call vault_show instead of hacking around LDAPRetrieve.


It's been changed to inherit from LDAPQuery instead.


NACK, it's not a LDAPQuery operation, because it has different
semantics. There is more to a command than executing code, so you should
use a correct base class.


Changed to inherit from Command as requested. Now these commands no
longer have a direct access to the vault object (self.obj) although they
are accessing vault objects like other vault commands. Also now the
vault name argument has to be added explicitly on each command.


You can inherit from crud.Retrieve and crud.Update to get self.obj and
the argument back.


I tried this:

   class vault_retrieve(Command, crud.Retrieve):

and it gave me an error:

   TypeError: Error when calling the metaclass bases
   Cannot create a consistent method resolution
   order (MRO) for bases Retrieve, Command

I'm sticking with the original code since it works fine although not ideal. I'm
not a Python expert, so if you know how to fix this properly please feel free
to post a patch on top of this.


If KRA is not installed, vault-archive and vault-retrieve fail with
internal error.


Added a code to check KRA installation in all vault commands. If you know a way
not to load the vault plugin if the KRA is not installed please let me know,
that's probably even better. Not sure how that will work on the client side
though.


The commands still behave differently based on whether they were called
from API which was initialized with in_server set to True or False.


That is unfortunately a restriction imposed by the framework. In order to
guarantee the security, the vault is designed to have separate client and
server code. The client code encrypts the secret, the server code forwards the
encrypted secret to KRA. To archive a secret into a vault properly, you are
supposed to call the client code. If you're calling the server code directly,
you are responsible to do your own encryption (i.e. generating session key,
nonce, and vault data).

If another plugin wants to use vault, it should implement a client code which
calls the vault client code to perform the archival from the client side.

What is the use case for calling the vault API from the server side anyway?
Wouldn't that defeat the purpose of having a vault? If a secret exists on the
server side in an unencrypted form doesn't it mean the secret may already have
been compromised?


There is no point in exposing the session_key, nonce and vault_data
options in CLI when their value is always overwritten in forward().


I agree there is no need to expose them in CLI, but in this framework the API
also defines the CLI. If there's a way to keep them in the server API but not
expose them in the CLI please let me know. Or, if there's a way to define
completely separate server API (without a matching client CLI) and client CLI
(without a matching server API) that will work too.


Will this always succeed?

+# deactivate vault record in KRA
+response = kra_client.keys.list_keys(
+client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)


Yes. If there's no active keys it will return an empty collection.


+for key_info in response.key_infos:
+kra_client.keys.modify_key_status(
+key_info.get_key_id(),
+pki.key.KeyClient.KEY_STATUS_INACTIVE)


This loop will do nothing given an empty collection.


If not, we might get into an inconsistent state, where the vault is
deleted in LDAP but still active in KRA. (I'm not sure if this is
actually a problem or not.)


That can only happen if the server crashes after deleting the vault but before
deactivating the key. Regardless, it will not be a problem because the key is
identified by vault ID/path so it will not conflict with other vaults, and it
will get overwritten if the same vault is recreated again.



Hi Endi,

Quickly skimming through your patches raised couple questions on my side:

1) Will it be possible to also store plain text password via Vault? It talks 
about taking in the binary data or the text file, but will it also work with 
plain user secrets (passwords)? I am talking about use like this:


# ipa vault-archive name --user mkosek --data Secret123

Re: [Freeipa-devel] [PATCH] Password vault

2015-06-01 Thread Endi Sukma Dewata

Please take a look at the updated patch.

On 5/27/2015 12:39 AM, Jan Cholasta wrote:

21) vault_archive is not a retrieve operation, it should be based on
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it
does
not do anything with LDAP. The same applies to vault_retrieve.


The vault_archive does not actually modify the LDAP entry because it
stores the data in KRA. It is actually an LDAPRetrieve operation
because
it needs to get the vault info before it can perform the archival
operation. Same thing with vault_retrieve.


It is not a LDAPRetrieve operation, because it has different
semantics.
Please use Command as base class and either use ldap2 for direct
LDAP or
call vault_show instead of hacking around LDAPRetrieve.


It's been changed to inherit from LDAPQuery instead.


NACK, it's not a LDAPQuery operation, because it has different
semantics. There is more to a command than executing code, so you should
use a correct base class.


Changed to inherit from Command as requested. Now these commands no
longer have a direct access to the vault object (self.obj) although they
are accessing vault objects like other vault commands. Also now the
vault name argument has to be added explicitly on each command.


You can inherit from crud.Retrieve and crud.Update to get self.obj and
the argument back.


I tried this:

  class vault_retrieve(Command, crud.Retrieve):

and it gave me an error:

  TypeError: Error when calling the metaclass bases
  Cannot create a consistent method resolution
  order (MRO) for bases Retrieve, Command

I'm sticking with the original code since it works fine although not 
ideal. I'm not a Python expert, so if you know how to fix this properly 
please feel free to post a patch on top of this.



If KRA is not installed, vault-archive and vault-retrieve fail with
internal error.


Added a code to check KRA installation in all vault commands. If you 
know a way not to load the vault plugin if the KRA is not installed 
please let me know, that's probably even better. Not sure how that will 
work on the client side though.



The commands still behave differently based on whether they were called
from API which was initialized with in_server set to True or False.


That is unfortunately a restriction imposed by the framework. In order 
to guarantee the security, the vault is designed to have separate client 
and server code. The client code encrypts the secret, the server code 
forwards the encrypted secret to KRA. To archive a secret into a vault 
properly, you are supposed to call the client code. If you're calling 
the server code directly, you are responsible to do your own encryption 
(i.e. generating session key, nonce, and vault data).


If another plugin wants to use vault, it should implement a client code 
which calls the vault client code to perform the archival from the 
client side.


What is the use case for calling the vault API from the server side 
anyway? Wouldn't that defeat the purpose of having a vault? If a secret 
exists on the server side in an unencrypted form doesn't it mean the 
secret may already have been compromised?



There is no point in exposing the session_key, nonce and vault_data
options in CLI when their value is always overwritten in forward().


I agree there is no need to expose them in CLI, but in this framework 
the API also defines the CLI. If there's a way to keep them in the 
server API but not expose them in the CLI please let me know. Or, if 
there's a way to define completely separate server API (without a 
matching client CLI) and client CLI (without a matching server API) that 
will work too.



Will this always succeed?

+# deactivate vault record in KRA
+response = kra_client.keys.list_keys(
+client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)


Yes. If there's no active keys it will return an empty collection.


+for key_info in response.key_infos:
+kra_client.keys.modify_key_status(
+key_info.get_key_id(),
+pki.key.KeyClient.KEY_STATUS_INACTIVE)


This loop will do nothing given an empty collection.


If not, we might get into an inconsistent state, where the vault is
deleted in LDAP but still active in KRA. (I'm not sure if this is
actually a problem or not.)


That can only happen if the server crashes after deleting the vault but 
before deactivating the key. Regardless, it will not be a problem 
because the key is identified by vault ID/path so it will not conflict 
with other vaults, and it will get overwritten if the same vault is 
recreated again.


--
Endi S. Dewata
From d1123f07745fea856ced305a814d933cd793dbf2 Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Tue, 21 Oct 2014 10:57:08 -0400
Subject: [PATCH] Added vault-archive and vault-retrieve commands.

New commands have been added to archive and retrieve
data into and from a vault, also to retrieve the
transport certificate.


Re: [Freeipa-devel] [PATCH] Password vault

2015-06-01 Thread Endi Sukma Dewata

On 5/28/2015 12:46 AM, Jan Cholasta wrote:

On a related note, since KRA is optional, can we move the vaults
container to cn=kra,cn=vaults? This is the convetion used by the other
optional components (DNS and recently CA).


I mean cn=vaults,cn=kra of course.


If you are talking about the o=kra,PKI suffix, I'm not sure whether 
the IPA framework will work with it.


If you are talking about adding a new cn=kra,IPA suffix entry on top 
of cn=vaults, what is the purpose of this entry? Is the entry going to 
be created/deleted automatically when the KRA is installed/removed? Is 
it going to be used for something else other than vaults?


There are a lot of questions that need to be answered before we can make 
this change. We probably should revisit this issue after the core vault 
functionality is added.


--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-05-27 Thread Jan Cholasta

Dne 27.5.2015 v 07:39 Jan Cholasta napsal(a):

Dne 27.5.2015 v 02:38 Endi Sukma Dewata napsal(a):

Please take a look at the attached patch to add vault-archive/retrieve
commands.

On 4/20/2015 1:12 AM, Jan Cholasta wrote:

16) You do way too much stuff in vault_add.forward(). Only code that
must be done on the client needs to be there, i.e. handling of the
data, text and in options.

The vault_archive call must be in vault_add.execute(), otherwise
a) we
will be making 2 RPC calls from the client and b) it won't be
called at
all when api.env.in_server is True.


This is done by design. The vault_add.forward() generates the salt
and
the keys. The vault_archive.forward() will encrypt the data. These
operations have to be done on the client side to secure the
transport of
the data from the client through the server and finally to KRA. This
mechanism prevents the server from looking at the unencrypted data.


OK, but that does not justify that it's broken in server-side API. It
can and should be done so that it works the same way on both client
and
server.

I think the best solution would be to split the command into two
commands, server-side vault_archive_raw to archive already encrypted
data, and client-side vault_archive to encrypt data and archive them
with vault_archive_raw in its .execute(). Same thing for
vault_retrieve.


Actually I think it's better to just merge the add and archive,
reducing
the number of RPC calls. The vault_archive now will support two
types of
operations:

(a) Archive data into a new vault (it will create the vault just before
archiving the data):

   $ ipa vault-archive testvault --create --in data ...

(b) Archive data into an existing vault:

   $ ipa vault-archive testvault --in data ...

The vault_add is now just a wrapper for the vault_archive(a).


If that's just an implementation detail, OK.

If it's possible to modify existing vault objects using vault-add or
create new objects using vault-archive, then NACK.


The vault-archive is now completely separate from vault-add. You can no
longer archive data while creating a vault:

   $ ipa vault-add test
   $ ipa vault-archive test --in secret.bin


OK.




BTW, I also think it would be better if there were 2 separate sets of
commands for binary and textual data
(vault_{archive,retrieve}_{data,text}) rather than trying to handle
everything in vault_{archive,retrieve}.


I don't think we want to provide a separate command of every possible
data type  operation combination. Users would get confused. The
archive
 retrieve commands should be able to handle all current  future data
types with options.


A command with two sets of mutually exclusive options is really two
commands in disguise, which is a good sign it should be divided into two
actual commands.

Who are you to say users would get confused? I say they would be more
confused by a command with a plethora of mutually exclusive options.

What other possible data types are there?


The patch has been simplified to support only binary data. The data can
be specified using either of these options:

   $ ipa vault-archive test --data base-64 encoded data
   $ ipa vault-archive test --in input file

I don't think we want to provide two separate commands for these options
although they are mutually exclusive, do we?


No, these are not really 2 different options, but rather 2 forms of the
same option, which for the lack of better support for files in the
framework have to be done as 2 options.




The add  archive combination was added for convenience, not for
optimization. This way you would be able to archive data into a new
vault using a single command. Without this, you'd have to execute two
separate commands: add  archive, which will result in 2 RPC calls
anyway.


I think I would prefer if it was separate, as that would be consistent
with other plugins (e.g. for objects with members, we don't allow
adding
members directly in -add, you have to use -add-member after -add).


The vault data is similar to group description, not group members. When
creating a group we can supply the description. If not specified it
will
be blank. Archiving vault data is similar to updating the group
description.


It's similar to group members because there are separate commands to
manipulate them.


Just because there are separate commands doesn't mean vault data
(single-valued) is similar to group members (multi-valued). It uses
separate commands because of the encryption steps involved while
archiving/retrieving data.


That was not the point, but whatever.




You have to choose one of:

   a) vault data is settable using vault-add and vault-mod and gettable
using vault-mod, vault-show and vault-find

   b) vault data is settable using vault-archive and gettable using
vault-retrieve

Anything in between is not permitted.


As mentioned above, the add and archive commands are now separate.


21) vault_archive is not a retrieve operation, it should be based on
LDAPUpdate instead of 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-27 Thread Jan Cholasta

Dne 28.5.2015 v 07:43 Jan Cholasta napsal(a):

Dne 27.5.2015 v 07:39 Jan Cholasta napsal(a):

Dne 27.5.2015 v 02:38 Endi Sukma Dewata napsal(a):

Please take a look at the attached patch to add vault-archive/retrieve
commands.

On 4/20/2015 1:12 AM, Jan Cholasta wrote:

16) You do way too much stuff in vault_add.forward(). Only code
that
must be done on the client needs to be there, i.e. handling of the
data, text and in options.

The vault_archive call must be in vault_add.execute(), otherwise
a) we
will be making 2 RPC calls from the client and b) it won't be
called at
all when api.env.in_server is True.


This is done by design. The vault_add.forward() generates the salt
and
the keys. The vault_archive.forward() will encrypt the data. These
operations have to be done on the client side to secure the
transport of
the data from the client through the server and finally to KRA. This
mechanism prevents the server from looking at the unencrypted data.


OK, but that does not justify that it's broken in server-side API. It
can and should be done so that it works the same way on both client
and
server.

I think the best solution would be to split the command into two
commands, server-side vault_archive_raw to archive already encrypted
data, and client-side vault_archive to encrypt data and archive them
with vault_archive_raw in its .execute(). Same thing for
vault_retrieve.


Actually I think it's better to just merge the add and archive,
reducing
the number of RPC calls. The vault_archive now will support two
types of
operations:

(a) Archive data into a new vault (it will create the vault just
before
archiving the data):

   $ ipa vault-archive testvault --create --in data ...

(b) Archive data into an existing vault:

   $ ipa vault-archive testvault --in data ...

The vault_add is now just a wrapper for the vault_archive(a).


If that's just an implementation detail, OK.

If it's possible to modify existing vault objects using vault-add or
create new objects using vault-archive, then NACK.


The vault-archive is now completely separate from vault-add. You can no
longer archive data while creating a vault:

   $ ipa vault-add test
   $ ipa vault-archive test --in secret.bin


OK.




BTW, I also think it would be better if there were 2 separate sets of
commands for binary and textual data
(vault_{archive,retrieve}_{data,text}) rather than trying to handle
everything in vault_{archive,retrieve}.


I don't think we want to provide a separate command of every possible
data type  operation combination. Users would get confused. The
archive
 retrieve commands should be able to handle all current  future data
types with options.


A command with two sets of mutually exclusive options is really two
commands in disguise, which is a good sign it should be divided into
two
actual commands.

Who are you to say users would get confused? I say they would be more
confused by a command with a plethora of mutually exclusive options.

What other possible data types are there?


The patch has been simplified to support only binary data. The data can
be specified using either of these options:

   $ ipa vault-archive test --data base-64 encoded data
   $ ipa vault-archive test --in input file

I don't think we want to provide two separate commands for these options
although they are mutually exclusive, do we?


No, these are not really 2 different options, but rather 2 forms of the
same option, which for the lack of better support for files in the
framework have to be done as 2 options.




The add  archive combination was added for convenience, not for
optimization. This way you would be able to archive data into a new
vault using a single command. Without this, you'd have to execute
two
separate commands: add  archive, which will result in 2 RPC calls
anyway.


I think I would prefer if it was separate, as that would be
consistent
with other plugins (e.g. for objects with members, we don't allow
adding
members directly in -add, you have to use -add-member after -add).


The vault data is similar to group description, not group members.
When
creating a group we can supply the description. If not specified it
will
be blank. Archiving vault data is similar to updating the group
description.


It's similar to group members because there are separate commands to
manipulate them.


Just because there are separate commands doesn't mean vault data
(single-valued) is similar to group members (multi-valued). It uses
separate commands because of the encryption steps involved while
archiving/retrieving data.


That was not the point, but whatever.




You have to choose one of:

   a) vault data is settable using vault-add and vault-mod and gettable
using vault-mod, vault-show and vault-find

   b) vault data is settable using vault-archive and gettable using
vault-retrieve

Anything in between is not permitted.


As mentioned above, the add and archive commands are now separate.


21) vault_archive is not a retrieve operation, it 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-26 Thread Endi Sukma Dewata
Please take a look at the attached patch to add vault-archive/retrieve 
commands.


On 4/20/2015 1:12 AM, Jan Cholasta wrote:

16) You do way too much stuff in vault_add.forward(). Only code that
must be done on the client needs to be there, i.e. handling of the
data, text and in options.

The vault_archive call must be in vault_add.execute(), otherwise a) we
will be making 2 RPC calls from the client and b) it won't be
called at
all when api.env.in_server is True.


This is done by design. The vault_add.forward() generates the salt and
the keys. The vault_archive.forward() will encrypt the data. These
operations have to be done on the client side to secure the
transport of
the data from the client through the server and finally to KRA. This
mechanism prevents the server from looking at the unencrypted data.


OK, but that does not justify that it's broken in server-side API. It
can and should be done so that it works the same way on both client and
server.

I think the best solution would be to split the command into two
commands, server-side vault_archive_raw to archive already encrypted
data, and client-side vault_archive to encrypt data and archive them
with vault_archive_raw in its .execute(). Same thing for vault_retrieve.


Actually I think it's better to just merge the add and archive, reducing
the number of RPC calls. The vault_archive now will support two types of
operations:

(a) Archive data into a new vault (it will create the vault just before
archiving the data):

   $ ipa vault-archive testvault --create --in data ...

(b) Archive data into an existing vault:

   $ ipa vault-archive testvault --in data ...

The vault_add is now just a wrapper for the vault_archive(a).


If that's just an implementation detail, OK.

If it's possible to modify existing vault objects using vault-add or
create new objects using vault-archive, then NACK.


The vault-archive is now completely separate from vault-add. You can no 
longer archive data while creating a vault:


  $ ipa vault-add test
  $ ipa vault-archive test --in secret.bin


BTW, I also think it would be better if there were 2 separate sets of
commands for binary and textual data
(vault_{archive,retrieve}_{data,text}) rather than trying to handle
everything in vault_{archive,retrieve}.


I don't think we want to provide a separate command of every possible
data type  operation combination. Users would get confused. The archive
 retrieve commands should be able to handle all current  future data
types with options.


A command with two sets of mutually exclusive options is really two
commands in disguise, which is a good sign it should be divided into two
actual commands.

Who are you to say users would get confused? I say they would be more
confused by a command with a plethora of mutually exclusive options.

What other possible data types are there?


The patch has been simplified to support only binary data. The data can 
be specified using either of these options:


  $ ipa vault-archive test --data base-64 encoded data
  $ ipa vault-archive test --in input file

I don't think we want to provide two separate commands for these options 
although they are mutually exclusive, do we?



The add  archive combination was added for convenience, not for
optimization. This way you would be able to archive data into a new
vault using a single command. Without this, you'd have to execute two
separate commands: add  archive, which will result in 2 RPC calls
anyway.


I think I would prefer if it was separate, as that would be consistent
with other plugins (e.g. for objects with members, we don't allow adding
members directly in -add, you have to use -add-member after -add).


The vault data is similar to group description, not group members. When
creating a group we can supply the description. If not specified it will
be blank. Archiving vault data is similar to updating the group
description.


It's similar to group members because there are separate commands to
manipulate them.


Just because there are separate commands doesn't mean vault data 
(single-valued) is similar to group members (multi-valued). It uses 
separate commands because of the encryption steps involved while 
archiving/retrieving data.



You have to choose one of:

   a) vault data is settable using vault-add and vault-mod and gettable
using vault-mod, vault-show and vault-find

   b) vault data is settable using vault-archive and gettable using
vault-retrieve

Anything in between is not permitted.


As mentioned above, the add and archive commands are now separate.


21) vault_archive is not a retrieve operation, it should be based on
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it does
not do anything with LDAP. The same applies to vault_retrieve.


The vault_archive does not actually modify the LDAP entry because it
stores the data in KRA. It is actually an LDAPRetrieve operation
because
it needs to get the vault info before it can perform the archival
operation. 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-26 Thread Jan Cholasta

Dne 27.5.2015 v 02:38 Endi Sukma Dewata napsal(a):

Please take a look at the attached patch to add vault-archive/retrieve
commands.

On 4/20/2015 1:12 AM, Jan Cholasta wrote:

16) You do way too much stuff in vault_add.forward(). Only code that
must be done on the client needs to be there, i.e. handling of the
data, text and in options.

The vault_archive call must be in vault_add.execute(), otherwise
a) we
will be making 2 RPC calls from the client and b) it won't be
called at
all when api.env.in_server is True.


This is done by design. The vault_add.forward() generates the salt and
the keys. The vault_archive.forward() will encrypt the data. These
operations have to be done on the client side to secure the
transport of
the data from the client through the server and finally to KRA. This
mechanism prevents the server from looking at the unencrypted data.


OK, but that does not justify that it's broken in server-side API. It
can and should be done so that it works the same way on both client and
server.

I think the best solution would be to split the command into two
commands, server-side vault_archive_raw to archive already encrypted
data, and client-side vault_archive to encrypt data and archive them
with vault_archive_raw in its .execute(). Same thing for
vault_retrieve.


Actually I think it's better to just merge the add and archive, reducing
the number of RPC calls. The vault_archive now will support two types of
operations:

(a) Archive data into a new vault (it will create the vault just before
archiving the data):

   $ ipa vault-archive testvault --create --in data ...

(b) Archive data into an existing vault:

   $ ipa vault-archive testvault --in data ...

The vault_add is now just a wrapper for the vault_archive(a).


If that's just an implementation detail, OK.

If it's possible to modify existing vault objects using vault-add or
create new objects using vault-archive, then NACK.


The vault-archive is now completely separate from vault-add. You can no
longer archive data while creating a vault:

   $ ipa vault-add test
   $ ipa vault-archive test --in secret.bin


OK.




BTW, I also think it would be better if there were 2 separate sets of
commands for binary and textual data
(vault_{archive,retrieve}_{data,text}) rather than trying to handle
everything in vault_{archive,retrieve}.


I don't think we want to provide a separate command of every possible
data type  operation combination. Users would get confused. The archive
 retrieve commands should be able to handle all current  future data
types with options.


A command with two sets of mutually exclusive options is really two
commands in disguise, which is a good sign it should be divided into two
actual commands.

Who are you to say users would get confused? I say they would be more
confused by a command with a plethora of mutually exclusive options.

What other possible data types are there?


The patch has been simplified to support only binary data. The data can
be specified using either of these options:

   $ ipa vault-archive test --data base-64 encoded data
   $ ipa vault-archive test --in input file

I don't think we want to provide two separate commands for these options
although they are mutually exclusive, do we?


No, these are not really 2 different options, but rather 2 forms of the 
same option, which for the lack of better support for files in the 
framework have to be done as 2 options.





The add  archive combination was added for convenience, not for
optimization. This way you would be able to archive data into a new
vault using a single command. Without this, you'd have to execute two
separate commands: add  archive, which will result in 2 RPC calls
anyway.


I think I would prefer if it was separate, as that would be consistent
with other plugins (e.g. for objects with members, we don't allow
adding
members directly in -add, you have to use -add-member after -add).


The vault data is similar to group description, not group members. When
creating a group we can supply the description. If not specified it will
be blank. Archiving vault data is similar to updating the group
description.


It's similar to group members because there are separate commands to
manipulate them.


Just because there are separate commands doesn't mean vault data
(single-valued) is similar to group members (multi-valued). It uses
separate commands because of the encryption steps involved while
archiving/retrieving data.


That was not the point, but whatever.




You have to choose one of:

   a) vault data is settable using vault-add and vault-mod and gettable
using vault-mod, vault-show and vault-find

   b) vault data is settable using vault-archive and gettable using
vault-retrieve

Anything in between is not permitted.


As mentioned above, the add and archive commands are now separate.


21) vault_archive is not a retrieve operation, it should be based on
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it
does
not 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-25 Thread Jan Cholasta

Dne 21.5.2015 v 17:45 Endi Sukma Dewata napsal(a):

Please take a look at the new patch.

On 5/20/2015 1:53 AM, Jan Cholasta wrote:

I suppose you meant you're OK with not adding host vaults now?


Yes.


The only way to know if the design will be future proof is if we have at
least some idea how it will be used. Without that there is no guarantee.

Host principals have this form: host/hostname@realm, so with the
current code they will be considered a service and will have a service
container.

Do you want to add a new cn=hosts container just for hosts? Unless we
have a specific reason (i.e. use case) I don't see a need to add
specific code for hosts now, or at least until we get the core vault
functionality working.


The reason is consistency. Private vaults should be available for all
identities, because anything else would be an arbitrary limitation
(which is not elegant). If private vaults were available for all
identities, we would need a container for host vaults. I'm not saying
the container has to be added now, but there should at least be a check
to reject requests when the authenticated identity is a host (i.e.
context.principal.startswith('host/')).


In the previous patch, since a host was considered a service it could
have private vaults too. But anyway, I added the code to reject host
principals as you requested.


When is the self.api actually initialized? Can we initialize the
container_dn (or base_dn as in the original code) attribute
immediately
after that?


Not yet, but this will be fixed in the future. (Also, container_dn is
part of the LDAPObject API, unlike base_dn used in the original code.)


Is there a ticket for this?


I don't think there is a ticket for this particular issue.


Added TODOs in the code.


This change is not included. The code will now obtain the values from
apilib.api.env at init time and store it in class attributes so it can
be reused.

 container_dn = api.env.container_vault
 base_dn = DN(container_dn, api.env.basedn)


Sorry, but no. Please just follow the best practice instead of
trying to
invent something new. This is not the right time and place to discuss
this. We should be discussing the vault, not framework idiosyncracies.


OK.


Thanks for understanding.


Changed the code as requested.


There is an obvious inefficiency here: all containers in the path
(including the built-in ones) will be re-added on every vault-add
operation.

I don't see anything wrong with recursions, especially if it works more
efficiently since only the immediate parent will be re-added.


I tend to stick to the don't use recursion in production code rule,
epsecially in simple cases like this one.


I think the rule is kind of misguided. Recursion might be considered bad
if it goes very deep thus consuming so much stack space, which is not
the case here given the short and flat tree topology. Or, if it's
unnecessary such as a tail-recursion, which is not the case here either.


So for example, with the loop every time you add a private vault you're
guaranteed to have three failed LDAP Add operations whereas with the
recursion there's only one failed operation.


This is not about loop vs. recursion, this is about the used approach.
Your code can be easily transformed into a loop while keeping the same
approach:

 entries = []

 while dn:
 assert dn.endswith(self.base_dn)

 rdn = dn[0]
 entry = self.backend.make_entry(
 dn,
 {
 'objectclass': ['nsContainer'],
 'cn': rdn['cn'],
 })

 # if entry can be added, return
 try:
 self.backend.add_entry(entry)
 break

 except errors.NotFound:
 pass

 # otherwise, create parent entry first
 dn = DN(*dn[1:])
 entries.insert(0, entry)

 for entry in entries:
 # then create the entry itself again
 self.backend.add_entry(entry)



Do you still want to use the loop?


Yes please.


This algorithm is recursive by nature (start at the bottom, but add the
parent first). The above code basically emulates recursion with two
loops and an explicit stack of entries, but the memory requirement is
pretty much the same because it's still using a stack. With real
recursion there is no loops and the stack is implicit, so the code is at
least cleaner.


I thought you cared about efficiency in the first place, given our 
discussion about container_dn. The looped variant is faster, even when 
it has 2 for loops, and consumes less memory, because of the function 
call overhead in the recursive variant.




If you really want to avoid recursion you probably should use an RDN
iterator instead of a stack, but the code would be either even uglier or
less efficient.

Anyway, it's not a big deal, I included this change.



Thanks, LGTM.

Pushed to master: fde21adcbd62b9a300740d9ba237ca9e89a905e4

--
Jan Cholasta

--
Manage your subscription for the 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-20 Thread Jan Cholasta

Dne 19.5.2015 v 16:40 Endi Sukma Dewata napsal(a):

Before I send another patch I have some questions below.

On 5/19/2015 3:27 AM, Jan Cholasta wrote:

I changed the 'host vaults' to become 'service vaults'. The interface
will look like this:

$ ipa vault-find --service HTTP/server.example.com
$ ipa vault-add test --service HTTP/server.example.com

I also added user vaults:

$ ipa vault-find --user testuser
$ ipa vault-add test --user testuser

Private vaults is a special case of user vaults where username=you.

Host vaults can be added later once we define the use case.


OK.


I suppose you meant you're OK with not adding host vaults now?


Yes.




4. The following code in get_dn() is incorrect:

   principal = getattr(context, 'principal')
   (name, realm) = split_principal(principal)
   name = name.split('/')
   if len(name) == 1:
   container_dn = DN(('cn', 'users'), container_dn)
   else:
   container_dn = DN(('cn', 'services'), container_dn)
   container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users
(cn=username,
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services,
cn=vaults is a service vault, not a container. The service vault is
used
by the admin to provide a secret for a service.

I'm not sure what the behavior should be if a service is executing a
vault command that uses a private container such as:

   $ ipa vault-add test

Maybe it should just generate an error.


Users, hosts and services are all user-like objects, is there a reason
not to support private vaults for all of them?


As mentioned above, it's not required in the design doc, but we can add
it if there's a clear use case. I agree that at least for now we can
change the service vault into a service container to store multiple
service's private vaults.


I don't really care about having a clear use case, I would prefer if the
design was elegant enough to handle *all* the cases without any extra
effort.


The only way to know if the design will be future proof is if we have at
least some idea how it will be used. Without that there is no guarantee.

Host principals have this form: host/hostname@realm, so with the
current code they will be considered a service and will have a service
container.

Do you want to add a new cn=hosts container just for hosts? Unless we
have a specific reason (i.e. use case) I don't see a need to add
specific code for hosts now, or at least until we get the core vault
functionality working.


The reason is consistency. Private vaults should be available for all 
identities, because anything else would be an arbitrary limitation 
(which is not elegant). If private vaults were available for all 
identities, we would need a container for host vaults. I'm not saying 
the container has to be added now, but there should at least be a check 
to reject requests when the authenticated identity is a host (i.e. 
context.principal.startswith('host/')).





5. In create_container() why do you need to reconstruct the
container_dn
on each invocation even though the value is fixed?

   container_dn = DN(self.container_dn, self.api.env.basedn)


Because self.api may not necessarily be the same as ipalib.api.


Under what scenario would that be a problem?


When someone uses the plugin with a different API object than ipalib.api.


The original code seems to

be working fine with ipalib.api.


The current best practice is to use self.api and *all* new plugin code
should do that.



If it is a problem, why do we still use ipalib.api to initialize
container_dn vault class attribute?

   container_dn = api.env.container_vault

Then in get_dn() we basically construct the container_dn variable with
values from both self.api and ipalib.api:

   container_dn = DN(self.container_dn, self.api.env.basedn)

When is the self.api actually initialized? Can we initialize the
container_dn (or base_dn as in the original code) attribute immediately
after that?


Not yet, but this will be fixed in the future. (Also, container_dn is
part of the LDAPObject API, unlike base_dn used in the original code.)


Is there a ticket for this?


I don't think there is a ticket for this particular issue.




This change is not included. The code will now obtain the values from
apilib.api.env at init time and store it in class attributes so it can
be reused.

 container_dn = api.env.container_vault
 base_dn = DN(container_dn, api.env.basedn)


Sorry, but no. Please just follow the best practice instead of trying to
invent something new. This is not the right time and place to discuss
this. We should be discussing the vault, not framework idiosyncracies.


OK.


Thanks for understanding.




6. The loop in create_container() is incorrect. Suppose we're
creating a
container cn=A, cn=B, suffix and the parent container cn=B,
suffix
doesn't exist yet. The first add_entry() invocation will fail as
expected, but instead of adding the parent entry the whole method
will
fail.


Right, 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-19 Thread Jan Cholasta

Dne 18.5.2015 v 21:17 Endi Sukma Dewata napsal(a):

Please take a look at the attached new patch which includes some of your
changes you proposed.

On 5/14/2015 7:17 PM, Endi Sukma Dewata wrote:

On 5/14/2015 1:42 PM, Jan Cholasta wrote:

Question: Services in IPA are identified by Kerberos principal. Why
are
service vaults identified by hostname alone?


The service vaults are actually identified by the hostname and service
name assuming the principal is in this format: name/host@realm.
The vault is stored in cn=name, cn=host, cn=services, cn=vaults,
suffix. When accessing a vault service you are supposed to specify
the
name and the host (except for vault-find which will return all services
in the same host):

$ ipa vault-find --host host
$ ipa vault-add name --host host

Are there other service principal formats that we need to support?
Do we
need to support services of different realms?


Well, users are identified by username (uid attribute), hosts by
hostname (fqdn attribute) and services by principal name
(krbprincipalname attribute). Each of them has separate container and is
also uniquely identified by principal name. I guess it would make sense
to follow that for vaults as well, in which case service vaults should
be called host vaults (because they are created in a host-specific
container, not a service-specific one) and maybe real service vaults
should be added.


There's no plan for host vaults in the design doc, but it's not
impossible to add it in the future. What is the use case?

I suppose we can change the service vault into a container, and possibly
add generic user vaults too (in addition to private user vaults), the
interface will look like this:

$ ipa vault-add PrivateVault
$ ipa vault-add ServiceVault --service name/hostname
$ ipa vault-add SharedVault --shared
$ ipa vault-add UsersVault --user username
$ ipa vault-add HostVault --host hostname

Basically we'll need a new parameter for each new container. For the
initial implementation we only need the first 2 or 3.


I changed the 'host vaults' to become 'service vaults'. The interface
will look like this:

$ ipa vault-find --service HTTP/server.example.com
$ ipa vault-add test --service HTTP/server.example.com

I also added user vaults:

$ ipa vault-find --user testuser
$ ipa vault-add test --user testuser

Private vaults is a special case of user vaults where username=you.

Host vaults can be added later once we define the use case.


OK.




1. The following code in get_dn() is causing problems for vault-find.

   dn = super(vault, self).get_dn(*keys, **options)
   rdn = dn[0]
   container_dn = DN(*dn[1:])

The super.get_dn() will return cn=vaults, suffix, so the rdn will
become cn=vaults and container_dn will become suffix. When combined
with the subcontainer (private/shared/service) it will produce an
invalid DN.


Right, fixed.

I should have tested the patch before posting it, my bad, sorry.


OK.


This change has been included in this patch.


OK.




2. Not sure if it'related to #1, the vault-find is failing.

$ ipa vault-find
ipa: ERROR: an internal error has occurred

The error_log shows TypeError: 'NoneType' object is not iterable


Fixed. It was caused by missing return value in vault_find.exc_callback.


We can actually ignore all NotFound errors since now all containers are
either created automatically or already created by default.

   if call_func.__name__ == 'find_entries':
   if isinstance(exc, errors.NotFound):
   shared = options.get('shared')

   # if private or service container has not been created, ignore
   if not shared:
   raise errors.EmptyResult(reason=str(exc))

The original code was only ignoring NotFound errors on user vaults
because previously only the user containers was supposed to be created
automatically, and there wasn't a plan to provide service container.


This change has been included and it will ignore all NotFound errors.


OK.




3. The --shared option in vault-find is now requiring an argument even
though it's a Flag.

$ ipa vault-find --shared
Usage: ipa [global-options] vault-find [CRITERIA] [options]

ipa: error: --shared option requires an argument


Fixed.


OK.


Not sure which code you changed, but the new patch doesn't exhibit this
problem.


I changed Flag('shared') to Flag('shared?').




4. The following code in get_dn() is incorrect:

   principal = getattr(context, 'principal')
   (name, realm) = split_principal(principal)
   name = name.split('/')
   if len(name) == 1:
   container_dn = DN(('cn', 'users'), container_dn)
   else:
   container_dn = DN(('cn', 'services'), container_dn)
   container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users (cn=username,
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services,
cn=vaults is a service vault, not a container. The service vault is
used
by the admin to provide a secret for a service.

I'm not sure what the behavior should 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-19 Thread Endi Sukma Dewata

Before I send another patch I have some questions below.

On 5/19/2015 3:27 AM, Jan Cholasta wrote:

I changed the 'host vaults' to become 'service vaults'. The interface
will look like this:

$ ipa vault-find --service HTTP/server.example.com
$ ipa vault-add test --service HTTP/server.example.com

I also added user vaults:

$ ipa vault-find --user testuser
$ ipa vault-add test --user testuser

Private vaults is a special case of user vaults where username=you.

Host vaults can be added later once we define the use case.


OK.


I suppose you meant you're OK with not adding host vaults now?


4. The following code in get_dn() is incorrect:

   principal = getattr(context, 'principal')
   (name, realm) = split_principal(principal)
   name = name.split('/')
   if len(name) == 1:
   container_dn = DN(('cn', 'users'), container_dn)
   else:
   container_dn = DN(('cn', 'services'), container_dn)
   container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users (cn=username,
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services,
cn=vaults is a service vault, not a container. The service vault is
used
by the admin to provide a secret for a service.

I'm not sure what the behavior should be if a service is executing a
vault command that uses a private container such as:

   $ ipa vault-add test

Maybe it should just generate an error.


Users, hosts and services are all user-like objects, is there a reason
not to support private vaults for all of them?


As mentioned above, it's not required in the design doc, but we can add
it if there's a clear use case. I agree that at least for now we can
change the service vault into a service container to store multiple
service's private vaults.


I don't really care about having a clear use case, I would prefer if the
design was elegant enough to handle *all* the cases without any extra
effort.


The only way to know if the design will be future proof is if we have at 
least some idea how it will be used. Without that there is no guarantee.


Host principals have this form: host/hostname@realm, so with the 
current code they will be considered a service and will have a service 
container.


Do you want to add a new cn=hosts container just for hosts? Unless we 
have a specific reason (i.e. use case) I don't see a need to add 
specific code for hosts now, or at least until we get the core vault 
functionality working.



5. In create_container() why do you need to reconstruct the
container_dn
on each invocation even though the value is fixed?

   container_dn = DN(self.container_dn, self.api.env.basedn)


Because self.api may not necessarily be the same as ipalib.api.


Under what scenario would that be a problem?


When someone uses the plugin with a different API object than ipalib.api.


The original code seems to

be working fine with ipalib.api.


The current best practice is to use self.api and *all* new plugin code
should do that.



If it is a problem, why do we still use ipalib.api to initialize
container_dn vault class attribute?

   container_dn = api.env.container_vault

Then in get_dn() we basically construct the container_dn variable with
values from both self.api and ipalib.api:

   container_dn = DN(self.container_dn, self.api.env.basedn)

When is the self.api actually initialized? Can we initialize the
container_dn (or base_dn as in the original code) attribute immediately
after that?


Not yet, but this will be fixed in the future. (Also, container_dn is
part of the LDAPObject API, unlike base_dn used in the original code.)


Is there a ticket for this?


This change is not included. The code will now obtain the values from
apilib.api.env at init time and store it in class attributes so it can
be reused.

 container_dn = api.env.container_vault
 base_dn = DN(container_dn, api.env.basedn)


Sorry, but no. Please just follow the best practice instead of trying to
invent something new. This is not the right time and place to discuss
this. We should be discussing the vault, not framework idiosyncracies.


OK.


6. The loop in create_container() is incorrect. Suppose we're
creating a
container cn=A, cn=B, suffix and the parent container cn=B, suffix
doesn't exist yet. The first add_entry() invocation will fail as
expected, but instead of adding the parent entry the whole method will
fail.


Right, fixed.


It's still not working. The new code is trying to add cn=vaults first,
and it stops because it already exists, but the intermediary entries are
still not added. Also the DN displayed in the message misleading:

$ ipa vault-add test
ipa: ERROR: container entry (cn=vaults) not found

$ ipa vault-add test --host server.example.com
ipa: ERROR: container entry (cn=vaults) not found

The unit tests are failing because of this.


I forgot to remove the break statement in the for loop.



This change is not included. The original code and the tests work just
fine.


I would prefer if it was done 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-18 Thread Endi Sukma Dewata
Please take a look at the attached new patch which includes some of your 
changes you proposed.


On 5/14/2015 7:17 PM, Endi Sukma Dewata wrote:

On 5/14/2015 1:42 PM, Jan Cholasta wrote:

Question: Services in IPA are identified by Kerberos principal. Why are
service vaults identified by hostname alone?


The service vaults are actually identified by the hostname and service
name assuming the principal is in this format: name/host@realm.
The vault is stored in cn=name, cn=host, cn=services, cn=vaults,
suffix. When accessing a vault service you are supposed to specify the
name and the host (except for vault-find which will return all services
in the same host):

$ ipa vault-find --host host
$ ipa vault-add name --host host

Are there other service principal formats that we need to support? Do we
need to support services of different realms?


Well, users are identified by username (uid attribute), hosts by
hostname (fqdn attribute) and services by principal name
(krbprincipalname attribute). Each of them has separate container and is
also uniquely identified by principal name. I guess it would make sense
to follow that for vaults as well, in which case service vaults should
be called host vaults (because they are created in a host-specific
container, not a service-specific one) and maybe real service vaults
should be added.


There's no plan for host vaults in the design doc, but it's not
impossible to add it in the future. What is the use case?

I suppose we can change the service vault into a container, and possibly
add generic user vaults too (in addition to private user vaults), the
interface will look like this:

$ ipa vault-add PrivateVault
$ ipa vault-add ServiceVault --service name/hostname
$ ipa vault-add SharedVault --shared
$ ipa vault-add UsersVault --user username
$ ipa vault-add HostVault --host hostname

Basically we'll need a new parameter for each new container. For the
initial implementation we only need the first 2 or 3.


I changed the 'host vaults' to become 'service vaults'. The interface 
will look like this:


$ ipa vault-find --service HTTP/server.example.com
$ ipa vault-add test --service HTTP/server.example.com

I also added user vaults:

$ ipa vault-find --user testuser
$ ipa vault-add test --user testuser

Private vaults is a special case of user vaults where username=you.

Host vaults can be added later once we define the use case.


1. The following code in get_dn() is causing problems for vault-find.

   dn = super(vault, self).get_dn(*keys, **options)
   rdn = dn[0]
   container_dn = DN(*dn[1:])

The super.get_dn() will return cn=vaults, suffix, so the rdn will
become cn=vaults and container_dn will become suffix. When combined
with the subcontainer (private/shared/service) it will produce an
invalid DN.


Right, fixed.

I should have tested the patch before posting it, my bad, sorry.


OK.


This change has been included in this patch.


2. Not sure if it'related to #1, the vault-find is failing.

$ ipa vault-find
ipa: ERROR: an internal error has occurred

The error_log shows TypeError: 'NoneType' object is not iterable


Fixed. It was caused by missing return value in vault_find.exc_callback.


We can actually ignore all NotFound errors since now all containers are
either created automatically or already created by default.

   if call_func.__name__ == 'find_entries':
   if isinstance(exc, errors.NotFound):
   shared = options.get('shared')

   # if private or service container has not been created, ignore
   if not shared:
   raise errors.EmptyResult(reason=str(exc))

The original code was only ignoring NotFound errors on user vaults
because previously only the user containers was supposed to be created
automatically, and there wasn't a plan to provide service container.


This change has been included and it will ignore all NotFound errors.


3. The --shared option in vault-find is now requiring an argument even
though it's a Flag.

$ ipa vault-find --shared
Usage: ipa [global-options] vault-find [CRITERIA] [options]

ipa: error: --shared option requires an argument


Fixed.


OK.


Not sure which code you changed, but the new patch doesn't exhibit this 
problem.



4. The following code in get_dn() is incorrect:

   principal = getattr(context, 'principal')
   (name, realm) = split_principal(principal)
   name = name.split('/')
   if len(name) == 1:
   container_dn = DN(('cn', 'users'), container_dn)
   else:
   container_dn = DN(('cn', 'services'), container_dn)
   container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users (cn=username,
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services,
cn=vaults is a service vault, not a container. The service vault is used
by the admin to provide a secret for a service.

I'm not sure what the behavior should be if a service is executing a
vault command that uses a private container such as:

   $ ipa vault-add test

Maybe it 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-14 Thread Jan Cholasta

Dne 14.5.2015 v 05:01 Endi Sukma Dewata napsal(a):

On 5/13/2015 4:09 AM, Jan Cholasta wrote:

Dne 12.5.2015 v 12:52 Endi Sukma Dewata napsal(a):

Please take a look at the attached patch (#353-9). It obsoletes all
previous patches. See comments below.

On 4/20/2015 1:12 AM, Jan Cholasta wrote:

I'm planning to merge the vault and vault container object and use the
vault type attribute to distinguish between the two. See more
discussion
about that below.


OK.


The vault container plugin has been removed instead of merged (see
explanation below). Internally the vaults are still stored in built-in
containers in the DS, but there won't be an interface to manage them.
The following containers are available for use: private, shared, and
services, but they are flat, not hierarchical.


To speed up the review, I have amended your patch with code and coding
style fixes (attached), please review my changes.

Question: Services in IPA are identified by Kerberos principal. Why are
service vaults identified by hostname alone?


The service vaults are actually identified by the hostname and service
name assuming the principal is in this format: name/host@realm.
The vault is stored in cn=name, cn=host, cn=services, cn=vaults,
suffix. When accessing a vault service you are supposed to specify the
name and the host (except for vault-find which will return all services
in the same host):

$ ipa vault-find --host host
$ ipa vault-add name --host host

Are there other service principal formats that we need to support? Do we
need to support services of different realms?


Well, users are identified by username (uid attribute), hosts by 
hostname (fqdn attribute) and services by principal name 
(krbprincipalname attribute). Each of them has separate container and is 
also uniquely identified by principal name. I guess it would make sense 
to follow that for vaults as well, in which case service vaults should 
be called host vaults (because they are created in a host-specific 
container, not a service-specific one) and maybe real service vaults 
should be added.



Do we
need to support services of different realms?


That depends. Do we want to support vaults for users and services from 
AD trusts?




Some comments about your changes:

1. The following code in get_dn() is causing problems for vault-find.

   dn = super(vault, self).get_dn(*keys, **options)
   rdn = dn[0]
   container_dn = DN(*dn[1:])

The super.get_dn() will return cn=vaults, suffix, so the rdn will
become cn=vaults and container_dn will become suffix. When combined
with the subcontainer (private/shared/service) it will produce an
invalid DN.


Right, fixed.

I should have tested the patch before posting it, my bad, sorry.



2. Not sure if it'related to #1, the vault-find is failing.

$ ipa vault-find
ipa: ERROR: an internal error has occurred

The error_log shows TypeError: 'NoneType' object is not iterable


Fixed. It was caused by missing return value in vault_find.exc_callback.



3. The --shared option in vault-find is now requiring an argument even
though it's a Flag.

$ ipa vault-find --shared
Usage: ipa [global-options] vault-find [CRITERIA] [options]

ipa: error: --shared option requires an argument


Fixed.



4. The following code in get_dn() is incorrect:

   principal = getattr(context, 'principal')
   (name, realm) = split_principal(principal)
   name = name.split('/')
   if len(name) == 1:
   container_dn = DN(('cn', 'users'), container_dn)
   else:
   container_dn = DN(('cn', 'services'), container_dn)
   container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users (cn=username,
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services,
cn=vaults is a service vault, not a container. The service vault is used
by the admin to provide a secret for a service.

I'm not sure what the behavior should be if a service is executing a
vault command that uses a private container such as:

   $ ipa vault-add test

Maybe it should just generate an error.


Users, hosts and services are all user-like objects, is there a reason 
not to support private vaults for all of them?




5. In create_container() why do you need to reconstruct the container_dn
on each invocation even though the value is fixed?

   container_dn = DN(self.container_dn, self.api.env.basedn)


Because self.api may not necessarily be the same as ipalib.api.



6. The loop in create_container() is incorrect. Suppose we're creating a
container cn=A, cn=B, suffix and the parent container cn=B, suffix
doesn't exist yet. The first add_entry() invocation will fail as
expected, but instead of adding the parent entry the whole method will
fail.

   while dn.endswith(container_dn):
   entry = self.backend.make_entry(
   dn,
   objectclass=['nsContainer'],
   cn=[dn[0]['cn']],
   )

   try:
   self.backend.add_entry(entry)
   except errors.DuplicateEntry:
   break

   dn = 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-14 Thread Endi Sukma Dewata

On 5/14/2015 1:42 PM, Jan Cholasta wrote:

Question: Services in IPA are identified by Kerberos principal. Why are
service vaults identified by hostname alone?


The service vaults are actually identified by the hostname and service
name assuming the principal is in this format: name/host@realm.
The vault is stored in cn=name, cn=host, cn=services, cn=vaults,
suffix. When accessing a vault service you are supposed to specify the
name and the host (except for vault-find which will return all services
in the same host):

$ ipa vault-find --host host
$ ipa vault-add name --host host

Are there other service principal formats that we need to support? Do we
need to support services of different realms?


Well, users are identified by username (uid attribute), hosts by
hostname (fqdn attribute) and services by principal name
(krbprincipalname attribute). Each of them has separate container and is
also uniquely identified by principal name. I guess it would make sense
to follow that for vaults as well, in which case service vaults should
be called host vaults (because they are created in a host-specific
container, not a service-specific one) and maybe real service vaults
should be added.


There's no plan for host vaults in the design doc, but it's not 
impossible to add it in the future. What is the use case?


I suppose we can change the service vault into a container, and possibly 
add generic user vaults too (in addition to private user vaults), the 
interface will look like this:


$ ipa vault-add PrivateVault
$ ipa vault-add ServiceVault --service name/hostname
$ ipa vault-add SharedVault --shared
$ ipa vault-add UsersVault --user username
$ ipa vault-add HostVault --host hostname

Basically we'll need a new parameter for each new container. For the 
initial implementation we only need the first 2 or 3.



Do we
need to support services of different realms?


That depends. Do we want to support vaults for users and services from
AD trusts?


It wasn't mentioned in the design doc either, but probably in the future 
we can support external vaults too:


$ ipa vault-add ExternalVault --principal principal

  cn=vaults
  + cn=external
+ cn=name/hostname@realm
  + cn=vault 1
  + cn=vault 2
+ cn=user@realm
  + cn=vault 3
  + cn=vault 4


1. The following code in get_dn() is causing problems for vault-find.

   dn = super(vault, self).get_dn(*keys, **options)
   rdn = dn[0]
   container_dn = DN(*dn[1:])

The super.get_dn() will return cn=vaults, suffix, so the rdn will
become cn=vaults and container_dn will become suffix. When combined
with the subcontainer (private/shared/service) it will produce an
invalid DN.


Right, fixed.

I should have tested the patch before posting it, my bad, sorry.


OK.


2. Not sure if it'related to #1, the vault-find is failing.

$ ipa vault-find
ipa: ERROR: an internal error has occurred

The error_log shows TypeError: 'NoneType' object is not iterable


Fixed. It was caused by missing return value in vault_find.exc_callback.


We can actually ignore all NotFound errors since now all containers are 
either created automatically or already created by default.


  if call_func.__name__ == 'find_entries':
  if isinstance(exc, errors.NotFound):
  shared = options.get('shared')

  # if private or service container has not been created, ignore
  if not shared:
  raise errors.EmptyResult(reason=str(exc))

The original code was only ignoring NotFound errors on user vaults 
because previously only the user containers was supposed to be created 
automatically, and there wasn't a plan to provide service container.



3. The --shared option in vault-find is now requiring an argument even
though it's a Flag.

$ ipa vault-find --shared
Usage: ipa [global-options] vault-find [CRITERIA] [options]

ipa: error: --shared option requires an argument


Fixed.


OK.


4. The following code in get_dn() is incorrect:

   principal = getattr(context, 'principal')
   (name, realm) = split_principal(principal)
   name = name.split('/')
   if len(name) == 1:
   container_dn = DN(('cn', 'users'), container_dn)
   else:
   container_dn = DN(('cn', 'services'), container_dn)
   container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users (cn=username,
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services,
cn=vaults is a service vault, not a container. The service vault is used
by the admin to provide a secret for a service.

I'm not sure what the behavior should be if a service is executing a
vault command that uses a private container such as:

   $ ipa vault-add test

Maybe it should just generate an error.


Users, hosts and services are all user-like objects, is there a reason
not to support private vaults for all of them?


As mentioned above, it's not required in the design doc, but we can add 
it if there's a clear use case. I agree that at least for now we can 
change the service 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-13 Thread Jan Cholasta

Dne 12.5.2015 v 12:52 Endi Sukma Dewata napsal(a):

Please take a look at the attached patch (#353-9). It obsoletes all
previous patches. See comments below.

On 4/20/2015 1:12 AM, Jan Cholasta wrote:

I'm planning to merge the vault and vault container object and use the
vault type attribute to distinguish between the two. See more discussion
about that below.


OK.


The vault container plugin has been removed instead of merged (see
explanation below). Internally the vaults are still stored in built-in
containers in the DS, but there won't be an interface to manage them.
The following containers are available for use: private, shared, and
services, but they are flat, not hierarchical.


To speed up the review, I have amended your patch with code and coding 
style fixes (attached), please review my changes.


Question: Services in IPA are identified by Kerberos principal. Why are 
service vaults identified by hostname alone?


--
Jan Cholasta
From 3996a1519b8408e751e0f1424eb4e2e69fda9ff6 Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Tue, 21 Oct 2014 10:57:08 -0400
Subject: [PATCH] Added vault plugin.

A new plugin has been added to manage vaults. Test scripts have
also been added to verify the functionality.

https://fedorahosted.org/freeipa/ticket/3872
---
 API.txt   |  69 ++
 VERSION   |   4 +-
 install/share/60basev3.ldif   |   1 +
 install/updates/40-vault.update   |  19 ++
 install/updates/Makefile.am   |   1 +
 ipa-client/man/default.conf.5 |   1 +
 ipalib/constants.py   |   1 +
 ipalib/plugins/vault.py   | 260 +++
 ipatests/test_xmlrpc/test_vault_plugin.py | 338 ++
 9 files changed, 692 insertions(+), 2 deletions(-)
 create mode 100644 install/updates/40-vault.update
 create mode 100644 ipalib/plugins/vault.py
 create mode 100644 ipatests/test_xmlrpc/test_vault_plugin.py

diff --git a/API.txt b/API.txt
index 346e35f..1ad73e4 100644
--- a/API.txt
+++ b/API.txt
@@ -4563,6 +4563,75 @@ option: Str('version?', exclude='webui')
 output: Output('result', type 'bool', None)
 output: Output('summary', (type 'unicode', type 'NoneType'), None)
 output: PrimaryKey('value', None, None)
+command: vault_add
+args: 1,8,3
+arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, required=True)
+option: Str('addattr*', cli_name='addattr', exclude='webui')
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
+option: Str('host?')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('setattr*', cli_name='setattr', exclude='webui')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('version?', exclude='webui')
+output: Entry('result', type 'dict', Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
+output: Output('summary', (type 'unicode', type 'NoneType'), None)
+output: PrimaryKey('value', None, None)
+command: vault_del
+args: 1,4,3
+arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, multivalue=True, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=True)
+option: Flag('continue', autofill=True, cli_name='continue', default=False)
+option: Str('host?')
+option: Flag('shared?', autofill=True, default=False)
+option: Str('version?', exclude='webui')
+output: Output('result', type 'dict', None)
+output: Output('summary', (type 'unicode', type 'NoneType'), None)
+output: ListOfPrimaryKeys('value', None, None)
+command: vault_find
+args: 1,10,4
+arg: Str('criteria?', noextrawhitespace=False)
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Str('cn', attribute=True, autofill=False, cli_name='vault_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, required=False)
+option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Str('host?')
+option: Flag('pkey_only?', autofill=True, default=False)
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Flag('shared?', autofill=True, default=False)
+option: Int('sizelimit?', autofill=False, minvalue=0)
+option: Int('timelimit?', autofill=False, minvalue=0)
+option: Str('version?', exclude='webui')
+output: Output('count', type 'int', None)
+output: ListOfEntries('result', (type 'list', type 'tuple'), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
+output: Output('summary', (type 'unicode', type 'NoneType'), None)
+output: Output('truncated', type 'bool', None)
+command: vault_mod
+args: 1,10,3
+arg: Str('cn', 

Re: [Freeipa-devel] [PATCH] Password vault

2015-05-13 Thread Endi Sukma Dewata

On 5/13/2015 4:09 AM, Jan Cholasta wrote:

Dne 12.5.2015 v 12:52 Endi Sukma Dewata napsal(a):

Please take a look at the attached patch (#353-9). It obsoletes all
previous patches. See comments below.

On 4/20/2015 1:12 AM, Jan Cholasta wrote:

I'm planning to merge the vault and vault container object and use the
vault type attribute to distinguish between the two. See more
discussion
about that below.


OK.


The vault container plugin has been removed instead of merged (see
explanation below). Internally the vaults are still stored in built-in
containers in the DS, but there won't be an interface to manage them.
The following containers are available for use: private, shared, and
services, but they are flat, not hierarchical.


To speed up the review, I have amended your patch with code and coding
style fixes (attached), please review my changes.

Question: Services in IPA are identified by Kerberos principal. Why are
service vaults identified by hostname alone?


The service vaults are actually identified by the hostname and service 
name assuming the principal is in this format: name/host@realm. 
The vault is stored in cn=name, cn=host, cn=services, cn=vaults, 
suffix. When accessing a vault service you are supposed to specify the 
name and the host (except for vault-find which will return all services 
in the same host):


$ ipa vault-find --host host
$ ipa vault-add name --host host

Are there other service principal formats that we need to support? Do we 
need to support services of different realms?


Some comments about your changes:

1. The following code in get_dn() is causing problems for vault-find.

  dn = super(vault, self).get_dn(*keys, **options)
  rdn = dn[0]
  container_dn = DN(*dn[1:])

The super.get_dn() will return cn=vaults, suffix, so the rdn will 
become cn=vaults and container_dn will become suffix. When combined 
with the subcontainer (private/shared/service) it will produce an 
invalid DN.


2. Not sure if it'related to #1, the vault-find is failing.

$ ipa vault-find
ipa: ERROR: an internal error has occurred

The error_log shows TypeError: 'NoneType' object is not iterable

3. The --shared option in vault-find is now requiring an argument even 
though it's a Flag.


$ ipa vault-find --shared
Usage: ipa [global-options] vault-find [CRITERIA] [options]

ipa: error: --shared option requires an argument

4. The following code in get_dn() is incorrect:

  principal = getattr(context, 'principal')
  (name, realm) = split_principal(principal)
  name = name.split('/')
  if len(name) == 1:
  container_dn = DN(('cn', 'users'), container_dn)
  else:
  container_dn = DN(('cn', 'services'), container_dn)
  container_dn = DN(('cn', name[-1]), container_dn)

A service does not have a private container like users (cn=username, 
cn=users, cn=vaults). The entry cn=name, cn=host, cn=services, 
cn=vaults is a service vault, not a container. The service vault is used 
by the admin to provide a secret for a service.


I'm not sure what the behavior should be if a service is executing a 
vault command that uses a private container such as:


  $ ipa vault-add test

Maybe it should just generate an error.

5. In create_container() why do you need to reconstruct the container_dn 
on each invocation even though the value is fixed?


  container_dn = DN(self.container_dn, self.api.env.basedn)

6. The loop in create_container() is incorrect. Suppose we're creating a 
container cn=A, cn=B, suffix and the parent container cn=B, suffix 
doesn't exist yet. The first add_entry() invocation will fail as 
expected, but instead of adding the parent entry the whole method will fail.


  while dn.endswith(container_dn):
  entry = self.backend.make_entry(
  dn,
  objectclass=['nsContainer'],
  cn=[dn[0]['cn']],
  )

  try:
  self.backend.add_entry(entry)
  except errors.DuplicateEntry:
  break

  dn = DN(*dn[1:])

7. The host and shared parameters are no longer available in vault-show 
and vault-del commands. The unit tests are failing because of that. Why 
do these commands not automatically inherit all parameters from the class?


--
Endi S. Dewata

--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code


Re: [Freeipa-devel] [PATCH] Password vault

2015-05-12 Thread Endi Sukma Dewata
Please take a look at the attached patch (#353-9). It obsoletes all 
previous patches. See comments below.


On 4/20/2015 1:12 AM, Jan Cholasta wrote:

I'm planning to merge the vault and vault container object and use the
vault type attribute to distinguish between the two. See more discussion
about that below.


OK.


The vault container plugin has been removed instead of merged (see 
explanation below). Internally the vaults are still stored in built-in 
containers in the DS, but there won't be an interface to manage them. 
The following containers are available for use: private, shared, and 
services, but they are flat, not hierarchical.



3) The container_vault config option should be renamed to
container_vaultcontainer, as it is used in the vaultcontainer plugin,
not the vault plugin.


It was named container_vault because it defines the DN for of the
subtree that contains all vault-related entries. I moved the base_dn
variable from vaultcontainer object to the vault object for clarity.


That does not make much sense to me. Vault objects are contained in
their respective vaultcontainer objects, not directly in cn=vaults.


The cn=vaults itself is actually a vault container (i.e.
ipaVaultContainer). Theoretically you could store a vault in any
container including cn=vaults, but we just don't want people to use it
that way.

I think this is consistent with other plugins. For example, the
container_user points to cn=users, which is an nsContainer. There is no
concept of 'user container' other than the cn=users itself. But even if
there is one, the container_user will still be stored in the user class.


In fact it is not consistent with other plugins. All entries managed by
the user plugin are stored *directly* under cn=users. Entries managed by
the vault plugin are not stored directly under cn=vaults, but rather
anywhere in the cn=vaults subtree and their DN is derived from the DN of
the parent vault container. For such objects, we don't set
plugin.container_dn and don't have container_plugin constant, but
rather define them as child objects of their container objects.


When the vault  vaultcontainer is merged, this will no longer be an
issue.


OK.


The vaults are still stored in the cn=vaults subtree, but now the 
containers will use nsContainer instead of ipaVaultContainer. The 
container_vault variable still defines the root container DN, i.e. 
cn=vaults.



4) The vault object should be child of the vaultcontainer object.

Not only is this correct from the object model perspective, but it
would
also make all the container_id hacks go away.


It's a bit difficult because it will affect how the container  vault
ID's are represented on the CLI.


Yes, but the API should be done right (without hacks) first. You can
tune the CLI after that if you want.


I think the current framework is rather limiting. It's kind of hard to
build an interface that looks exactly what you want then add the
implementation later to match the interface because many things are
interrelated. In this particular case the object hierarchy on the server
side would affect how the vault ID will be represented on the client
side.


It indeed is limiting and that's a good thing. We don't want people to
be able to create any crazy interfaces they can imagine, inconsistent
with everything else in IPA.


So the vault container plugin was removed because the current framework 
cannot support the hierarchical structure described in the vault design 
without overriding the default parameter handling (which was referred to 
as 'hacks', although it was actually suggested by the previous 
reviewer). Adding the missing functionality will require modifications 
to the base framework classes. Such changes should only be done after 
thoroughly evaluating the impact on the existing plugins, probably in a 
future release.



In the design the container ID would be a single value like this:

   $ ipa vault-add /services/server.example.com/HTTP

And if the vault ID is relative (without initial slash), it will be
appended to the user's private container (i.e. /users/username/):

   $ ipa vault-add PrivateVault

The implementation is not complete yet. Currently it accepts this
format:

   $ ipa vault-add vault name [--container container ID]

and I'm still planning to add this:

   $ ipa vault-add vault ID


This is actually now done in the latest patch. Internally the ID is
still split into name  parent ID.


If the vault must be a child of vaultcontainer, and the vaultcontainer
must be a child of a vaultcontainer, does it mean the vault ID would
have to be split into separate arguments like this?

   $ ipa vaultcontainer-add services server.example.com HTTP

If that's the case we'd lose the ability to specify a relative vault
ID.


Yes, that's the case.

But I don't think relative IDs should be a problem, we can do this:

 $ ipa vaultcontainer-add a b c  # absolute
 $ ipa vaultcontainer-add . c# relative


I think a . will be 

Re: [Freeipa-devel] [PATCH] Password vault

2015-04-20 Thread Jan Cholasta

Dne 3.4.2015 v 05:37 Endi Sukma Dewata napsal(a):

Hi,

Attached are new patches replacing all old ones. Please take a look at
them. They should applied in this order: 365, 353-8, 355-6, 357-3,
359-2, 360-1, 364-1, 361-1.


Thanks for squashing patches 362-364 into the original patches, it's 
much more digestible this way.




I'm planning to merge the vault and vault container object and use the
vault type attribute to distinguish between the two. See more discussion
about that below.


OK.


3) The container_vault config option should be renamed to
container_vaultcontainer, as it is used in the vaultcontainer plugin,
not the vault plugin.


It was named container_vault because it defines the DN for of the
subtree that contains all vault-related entries. I moved the base_dn
variable from vaultcontainer object to the vault object for clarity.


That does not make much sense to me. Vault objects are contained in
their respective vaultcontainer objects, not directly in cn=vaults.


The cn=vaults itself is actually a vault container (i.e.
ipaVaultContainer). Theoretically you could store a vault in any
container including cn=vaults, but we just don't want people to use it
that way.

I think this is consistent with other plugins. For example, the
container_user points to cn=users, which is an nsContainer. There is no
concept of 'user container' other than the cn=users itself. But even if
there is one, the container_user will still be stored in the user class.


In fact it is not consistent with other plugins. All entries managed by 
the user plugin are stored *directly* under cn=users. Entries managed by 
the vault plugin are not stored directly under cn=vaults, but rather 
anywhere in the cn=vaults subtree and their DN is derived from the DN of 
the parent vault container. For such objects, we don't set 
plugin.container_dn and don't have container_plugin constant, but 
rather define them as child objects of their container objects.




When the vault  vaultcontainer is merged, this will no longer be an issue.


OK.




4) The vault object should be child of the vaultcontainer object.

Not only is this correct from the object model perspective, but it
would
also make all the container_id hacks go away.


It's a bit difficult because it will affect how the container  vault
ID's are represented on the CLI.


Yes, but the API should be done right (without hacks) first. You can
tune the CLI after that if you want.


I think the current framework is rather limiting. It's kind of hard to
build an interface that looks exactly what you want then add the
implementation later to match the interface because many things are
interrelated. In this particular case the object hierarchy on the server
side would affect how the vault ID will be represented on the client side.


It indeed is limiting and that's a good thing. We don't want people to 
be able to create any crazy interfaces they can imagine, inconsistent 
with everything else in IPA.





In the design the container ID would be a single value like this:

   $ ipa vault-add /services/server.example.com/HTTP

And if the vault ID is relative (without initial slash), it will be
appended to the user's private container (i.e. /users/username/):

   $ ipa vault-add PrivateVault

The implementation is not complete yet. Currently it accepts this
format:

   $ ipa vault-add vault name [--container container ID]

and I'm still planning to add this:

   $ ipa vault-add vault ID


This is actually now done in the latest patch. Internally the ID is
still split into name  parent ID.


If the vault must be a child of vaultcontainer, and the vaultcontainer
must be a child of a vaultcontainer, does it mean the vault ID would
have to be split into separate arguments like this?

   $ ipa vaultcontainer-add services server.example.com HTTP

If that's the case we'd lose the ability to specify a relative vault ID.


Yes, that's the case.

But I don't think relative IDs should be a problem, we can do this:

 $ ipa vaultcontainer-add a b c  # absolute
 $ ipa vaultcontainer-add . c# relative


I think a . will be confusing because there's no concept of current
vaultcontainer like current directory.


or this:

 $ ipa vaultcontainer-add '' a b c  # absolute
 $ ipa vaultcontainer-add c # relative


An empty string is also confusing and can be problematic to distinguish
with missing argument.


I didn't mean empty string specifically, it could have been any special 
value.





or this:

 $ ipa vaultcontainer-add a b c # absolute
 $ ipa vaultcontainer-add c --relative  # relative

or this:

 $ ipa vaultcontainer-add a b c --absolute  # absolute
 $ ipa vaultcontainer-add c # relative


Per discussion in the IPA-CS meeting, we'd rather keep the / for vault
ID delimiters because the spaces will be confusing to users, but we'll
not use absolute ID anymore.


I'm sorry if I gave you the impression that this is up for discussion, 

Re: [Freeipa-devel] [PATCH] Password vault

2015-03-23 Thread Jan Cholasta

Dne 11.3.2015 v 15:12 Endi Sukma Dewata napsal(a):

Thanks for the review. New patch attached to be applied on top of all
previous patches. Please see comments below.


Thanks. I have replied to some of your comments below.



On 3/6/2015 3:53 PM, Jan Cholasta wrote:

Patch 353:

1) Please follow PEP8 in new code.

The pep8 tool reports these errors in existing files:

./ipalib/constants.py:98:80: E501 line too long (84  79 characters)
./ipalib/plugins/baseldap.py:1527:80: E501 line too long (81  79
characters)
./ipalib/plugins/user.py:915:80: E501 line too long (80  79 characters)

as well as many errors in the files this patch adds.


For some reason pylint keeps crashing during build so I cannot run it
for all files. I'm fixing the errors that I can see. If you see other
errors please let me know while I'm still trying to figure out the problem.


Well, I did not use pylint, but pep8: 
http://pep8.readthedocs.org/en/latest/




Is there an existing ticket for fixing PEP8 errors? Let's use that for
fixing the errors in the existing code.


There is no ticket, but we still follow PEP8 in new code, so please do 
that. It shouldn't be too hard.



...


3) The container_vault config option should be renamed to
container_vaultcontainer, as it is used in the vaultcontainer plugin,
not the vault plugin.


It was named container_vault because it defines the DN for of the
subtree that contains all vault-related entries. I moved the base_dn
variable from vaultcontainer object to the vault object for clarity.


That does not make much sense to me. Vault objects are contained in 
their respective vaultcontainer objects, not directly in cn=vaults.





4) The vault object should be child of the vaultcontainer object.

Not only is this correct from the object model perspective, but it would
also make all the container_id hacks go away.


It's a bit difficult because it will affect how the container  vault
ID's are represented on the CLI.


Yes, but the API should be done right (without hacks) first. You can 
tune the CLI after that if you want.




In the design the container ID would be a single value like this:

   $ ipa vault-add /services/server.example.com/HTTP

And if the vault ID is relative (without initial slash), it will be
appended to the user's private container (i.e. /users/username/):

   $ ipa vault-add PrivateVault

The implementation is not complete yet. Currently it accepts this format:

   $ ipa vault-add vault name [--container container ID]

and I'm still planning to add this:

   $ ipa vault-add vault ID

If the vault must be a child of vaultcontainer, and the vaultcontainer
must be a child of a vaultcontainer, does it mean the vault ID would
have to be split into separate arguments like this?

   $ ipa vaultcontainer-add services server.example.com HTTP

If that's the case we'd lose the ability to specify a relative vault ID.


Yes, that's the case.

But I don't think relative IDs should be a problem, we can do this:

$ ipa vaultcontainer-add a b c  # absolute
$ ipa vaultcontainer-add . c# relative

or this:

$ ipa vaultcontainer-add '' a b c  # absolute
$ ipa vaultcontainer-add c # relative

or this:

$ ipa vaultcontainer-add a b c # absolute
$ ipa vaultcontainer-add c --relative  # relative

or this:

$ ipa vaultcontainer-add a b c --absolute  # absolute
$ ipa vaultcontainer-add c # relative


...


11) No clever optimizations like this please:

+# vault DN cannot be the container base DN
+if len(dn) == len(api.Object.vaultcontainer.base_dn):
+raise ValueError('Invalid vault DN: %s' % dn)

Compare the DNs by value instead.


Actually the DN values have already been compared in the code right
above it:

 # make sure the DN is a vault DN
 if not dn.endswith(self.api.Object.vaultcontainer.base_dn):
 raise ValueError('Invalid vault DN: %s' % dn)

This code confirms that the incoming vault DN is within the vault
subtree. After that, the DN length comparison above is just to make sure
the incoming vault DN is not the root of the vault subtree itself. It
doesn't need to compare the values again.


I see. You can combine both of the checks into one:

if not dn.endswith(self.api.Object.vaultcontainer.base_dn, 1):
raise ValueError(...)


...


14) Use File instead of Str for input files:

+Str('in?',
+cli_name='in',
+doc=_('File containing data to archive'),
+),


The File type doesn't work with binary files because it tries to decode
the content.


OK. I know File is broken and plan to fix it in the future. Just add a 
comment saying that it should be a File, but it's broken, OK?



...


16) You do way too much stuff in vault_add.forward(). Only code that
must be done on the client needs to be there, i.e. handling of the
data, text and in options.

The vault_archive call must be in vault_add.execute(), otherwise a) we
will be making 2 

Re: [Freeipa-devel] [PATCH] Password vault

2015-03-16 Thread Endi Sukma Dewata

On 3/13/2015 2:27 AM, Endi Sukma Dewata wrote:

On 3/11/2015 9:12 PM, Endi Sukma Dewata wrote:

Thanks for the review. New patch attached to be applied on top of all
previous patches. Please see comments below.


New patch #362-1 attached replacing #362. It fixed some issues in
handle_not_found().


New patch #363 attached. It adds supports for vault  vaultcontainer ID 
parameter.


--
Endi S. Dewata
From e1d2a3a62e6d16c1c9b19f4cb19b900427ea5e1f Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Thu, 12 Mar 2015 09:21:02 -0400
Subject: [PATCH] Vault ID improvements.

The vault plugin has been modified to accept a single vault ID
in addition to separate name and parent ID attributes. The vault
container has also been modified in the same way. New test cases
have been added to verify this functionality.

https://fedorahosted.org/freeipa/ticket/3872
---
 ipalib/plugins/vault.py| 143 +--
 ipalib/plugins/vaultcontainer.py   | 137 +--
 ipalib/plugins/vaultsecret.py  |  10 +-
 ipatests/test_xmlrpc/test_vault_plugin.py  | 151 +
 ipatests/test_xmlrpc/test_vaultcontainer_plugin.py |  90 ++--
 ipatests/test_xmlrpc/test_vaultsecret_plugin.py| 115 
 6 files changed, 565 insertions(+), 81 deletions(-)

diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index 
d47067758186601365e5924f5d13c7ab51ba66e5..38693d0710e000695cae21fb4db5dfb4c85b5c74
 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -61,7 +61,7 @@ EXAMPLES:
ipa vault-find
 ) + _(
  List shared vaults:
-   ipa vault-find --container-id /shared
+   ipa vault-find /shared
 ) + _(
  Add a standard vault:
ipa vault-add MyVault
@@ -171,8 +171,8 @@ class vault(LDAPObject):
 cli_name='vault_name',
 label=_('Vault name'),
 primary_key=True,
-pattern='^[a-zA-Z0-9_.-]+$',
-pattern_errmsg='may only include letters, numbers, _, ., and -',
+pattern='^[a-zA-Z0-9_.-/]+$',
+pattern_errmsg='may only include letters, numbers, _, ., -, and /',
 maxlength=255,
 ),
 Str('vault_id?',
@@ -217,7 +217,7 @@ class vault(LDAPObject):
 
 # get vault ID from parameters
 name = keys[-1]
-container_id = 
self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+container_id = 
self.api.Object.vaultcontainer.absolute_id(options.get('container_id'))
 vault_id = container_id + name
 
 dn = self.base_dn
@@ -250,6 +250,81 @@ class vault(LDAPObject):
 
 return id
 
+def split_id(self, id):
+
+Splits a vault ID into (vault name, container ID) tuple.
+
+
+if not id:
+return (None, None)
+
+# split ID into container ID and vault name
+parts = id.rsplit(u'/', 1)
+
+if len(parts) == 2:
+vault_name = parts[1]
+container_id = u'%s/' % parts[0]
+
+else:
+vault_name = parts[0]
+container_id = None
+
+if not vault_name:
+vault_name = None
+
+return (vault_name, container_id)
+
+def merge_id(self, vault_name, container_id):
+
+Merges a vault name and a container ID into a vault ID.
+
+
+if not vault_name:
+id = container_id
+
+elif vault_name.startswith('/') or not container_id:
+id = vault_name
+
+else:
+id = container_id + vault_name
+
+return id
+
+def normalize_params(self, *args, **options):
+
+Normalizes the vault ID in the parameters.
+
+
+vault_id = self.parse_params(*args, **options)
+(vault_name, container_id) = self.split_id(vault_id)
+return self.update_params(vault_name, container_id, *args, **options)
+
+def parse_params(self, *args, **options):
+
+Extracts the vault name and container ID in the parameters.
+
+
+# get vault name and container ID from parameters
+vault_name = args[0]
+if type(vault_name) is tuple:
+vault_name = vault_name[0]
+container_id = 
self.api.Object.vaultcontainer.normalize_id(options.get('container_id'))
+
+return self.merge_id(vault_name, container_id)
+
+def update_params(self, new_vault_name, new_container_id, *args, 
**options):
+
+Stores vault name and container ID back into the parameters.
+
+
+args_list = list(args)
+args_list[0] = new_vault_name
+args = tuple(args_list)
+
+options['container_id'] = new_container_id
+
+return (args, options)
+
 def get_kra_id(self, id):
 
 Generates a client key ID to store/retrieve data in KRA.
@@ -363,10 +438,14 @@ class vault_add(LDAPCreate):
 
 msg_summary = _('Added 

Re: [Freeipa-devel] [PATCH] Password vault

2015-03-12 Thread Endi Sukma Dewata
Thanks for the review. New patch attached to be applied on top of all 
previous patches. Please see comments below.


On 3/6/2015 3:53 PM, Jan Cholasta wrote:

Patch 353:

1) Please follow PEP8 in new code.

The pep8 tool reports these errors in existing files:

./ipalib/constants.py:98:80: E501 line too long (84  79 characters)
./ipalib/plugins/baseldap.py:1527:80: E501 line too long (81  79
characters)
./ipalib/plugins/user.py:915:80: E501 line too long (80  79 characters)

as well as many errors in the files this patch adds.


For some reason pylint keeps crashing during build so I cannot run it 
for all files. I'm fixing the errors that I can see. If you see other 
errors please let me know while I'm still trying to figure out the problem.


Is there an existing ticket for fixing PEP8 errors? Let's use that for 
fixing the errors in the existing code.



2) Pylint reports the following error:

ipatests/test_xmlrpc/test_vault_plugin.py:153:
[E0102(function-redefined), test_vault] class already defined line 27)


Fixed.


3) The container_vault config option should be renamed to
container_vaultcontainer, as it is used in the vaultcontainer plugin,
not the vault plugin.


It was named container_vault because it defines the DN for of the 
subtree that contains all vault-related entries. I moved the base_dn 
variable from vaultcontainer object to the vault object for clarity.



4) The vault object should be child of the vaultcontainer object.

Not only is this correct from the object model perspective, but it would
also make all the container_id hacks go away.


It's a bit difficult because it will affect how the container  vault 
ID's are represented on the CLI.


In the design the container ID would be a single value like this:

  $ ipa vault-add /services/server.example.com/HTTP

And if the vault ID is relative (without initial slash), it will be 
appended to the user's private container (i.e. /users/username/):


  $ ipa vault-add PrivateVault

The implementation is not complete yet. Currently it accepts this format:

  $ ipa vault-add vault name [--container container ID]

and I'm still planning to add this:

  $ ipa vault-add vault ID

If the vault must be a child of vaultcontainer, and the vaultcontainer 
must be a child of a vaultcontainer, does it mean the vault ID would 
have to be split into separate arguments like this?


  $ ipa vaultcontainer-add services server.example.com HTTP

If that's the case we'd lose the ability to specify a relative vault ID.


5) When specifying param flags, use set literals.

This is especially wrong, because it's not a tuple, but a string in
parentheses:

+flags=('virtual_attribute'),


Fixed.


6) The `container` param of vault should actually be an option in
vault_* commands.

Also it should be renamed to `container_id`, for consistency with
vaultcontainer.


Fixed. It was actually made to be consistent with the 'parent' attribute 
in the vaultcontainer class. Now the 'parent' has been renamed to 
'parent_id' as well.



7) The `vault_id` param of vault should have no_option in flags, since
it is output-only.


Fixed.


8) Don't translate docstrings where not necessary:

+def get_dn(self, *keys, **options):
+__doc__ = _(
+Generates vault DN from vault ID.
+)

Only plugin modules and classes should have translated docstrings.


Fixed.


9) This looks wrong in vault.get_dn() and vaultcontainer.get_dn():

+name = None
+if keys:
+name = keys[0]

Primary key of the object should always be set, so the if statement
should not be there.


Fixed.


Also, primary key of any given object is always last in keys, so use
keys[-1] instead of keys[0].


Fixed.


10) Use self.api instead of api to access the API in plugins.


Fixed.


11) No clever optimizations like this please:

+# vault DN cannot be the container base DN
+if len(dn) == len(api.Object.vaultcontainer.base_dn):
+raise ValueError('Invalid vault DN: %s' % dn)

Compare the DNs by value instead.


Actually the DN values have already been compared in the code right 
above it:


# make sure the DN is a vault DN
if not dn.endswith(self.api.Object.vaultcontainer.base_dn):
raise ValueError('Invalid vault DN: %s' % dn)

This code confirms that the incoming vault DN is within the vault 
subtree. After that, the DN length comparison above is just to make sure 
the incoming vault DN is not the root of the vault subtree itself. It 
doesn't need to compare the values again.



12) vault.split_id() is not used anywhere.


Removed.


13) Bytes is not base64-encoded data:

+Bytes('data?',
+cli_name='data',
+doc=_('Base-64 encoded binary data to archive'),
+),

It is base64-encoded in the CLI, but on the API level it is not. The doc
should say just Binary data to archive.


Fixed.


14) Use File instead of Str for input files:

+Str('in?',
+cli_name='in',
+ 

Re: [Freeipa-devel] [PATCH] Password vault

2015-03-12 Thread Endi Sukma Dewata

On 3/11/2015 9:12 PM, Endi Sukma Dewata wrote:

Thanks for the review. New patch attached to be applied on top of all
previous patches. Please see comments below.


New patch #362-1 attached replacing #362. It fixed some issues in 
handle_not_found().


--
Endi S. Dewata
From 6741138b647427cd3448ff72369dfc6fa21354aa Mon Sep 17 00:00:00 2001
From: Endi S. Dewata edew...@redhat.com
Date: Mon, 9 Mar 2015 12:09:20 -0400
Subject: [PATCH] Vault improvements.

The vault plugins have been modified to clean up the code, to fix
some issues, and to improve error handling. The LDAPCreate and
LDAPSearch classes have been refactored to allow subclasses to
provide custom error handling. The test scripts have been updated
accordingly.

https://fedorahosted.org/freeipa/ticket/3872
---
 API.txt|  50 ++--
 ipalib/plugins/baseldap.py |  35 +--
 ipalib/plugins/user.py |   6 +-
 ipalib/plugins/vault.py| 273 ++---
 ipalib/plugins/vaultcontainer.py   | 226 +
 ipalib/plugins/vaultsecret.py  | 108 
 ipatests/test_xmlrpc/test_vault_plugin.py  |   2 +-
 ipatests/test_xmlrpc/test_vaultcontainer_plugin.py |  24 +-
 ipatests/test_xmlrpc/test_vaultsecret_plugin.py|   2 +-
 9 files changed, 371 insertions(+), 355 deletions(-)

diff --git a/API.txt b/API.txt
index 
ffbffa78cde372d5c7027b758be58bf07caebbc6..3a741755ab3e15e0175599a16a090b04d46d6be8
 100644
--- a/API.txt
+++ b/API.txt
@@ -4518,7 +4518,7 @@ args: 1,20,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
-option: Str('container', attribute=False, cli_name='container', 
multivalue=False, pattern='^[a-zA-Z0-9_.-/]+$', required=False)
+option: Str('container_id?', cli_name='container_id')
 option: Bytes('data?', cli_name='data')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, 
required=False)
 option: Str('escrow_public_key_file?', cli_name='escrow_public_key_file')
@@ -4543,7 +4543,7 @@ command: vault_add_member
 args: 1,7,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, 
required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
-option: Str('container?', cli_name='container')
+option: Str('container_id?', cli_name='container_id')
 option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, 
exclude='webui')
@@ -4556,7 +4556,7 @@ command: vault_add_owner
 args: 1,7,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, 
required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
-option: Str('container?', cli_name='container')
+option: Str('container_id?', cli_name='container_id')
 option: Str('group*', alwaysask=True, cli_name='groups', csv=True)
 option: Flag('no_members', autofill=True, default=False, exclude='webui')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, 
exclude='webui')
@@ -4569,7 +4569,7 @@ command: vault_archive
 args: 1,15,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, 
multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, 
required=True)
 option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
-option: Str('container?', cli_name='container')
+option: Str('container_id?', cli_name='container_id')
 option: Bytes('data?', cli_name='data')
 option: Bytes('encryption_key?', cli_name='encryption_key')
 option: Str('in?', cli_name='in')
@@ -4589,7 +4589,7 @@ output: PrimaryKey('value', None, None)
 command: vault_del
 args: 1,3,3
 arg: Str('cn', attribute=True, cli_name='vault_name', maxlength=255, 
multivalue=True, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, query=True, 
required=True)
-option: Str('container?', cli_name='container')
+option: Str('container_id?', cli_name='container_id')
 option: Flag('continue', autofill=True, cli_name='continue', default=False)
 option: Str('version?', exclude='webui')
 output: Output('result', type 'dict', None)
@@ -4600,7 +4600,7 @@ args: 1,15,4
 arg: Str('criteria?', noextrawhitespace=False)
 option: Flag('all', autofill=True, cli_name='all', default=False, 
exclude='webui')
 option: Str('cn', attribute=True, autofill=False, cli_name='vault_name', 
maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.-]+$', primary_key=True, 

Re: [Freeipa-devel] [PATCH] Password vault

2015-03-06 Thread Jan Cholasta

Hi Endi,

Dne 24.2.2015 v 04:09 Endi Sukma Dewata napsal(a):

On 2/16/2015 2:50 AM, Endi Sukma Dewata wrote:

Hi,

Attached are the updated patches for the password vault, and some new
ones (please disregard previous patch submissions). Please give them a
try. Thanks.


New patches attached replacing all previous vault patches. They include
the new escrow functionality, changes to the asymmetric vault, and some
cleanups. Thanks.



Patch 353:

1) Please follow PEP8 in new code.

The pep8 tool reports these errors in existing files:

./ipalib/constants.py:98:80: E501 line too long (84  79 characters)
./ipalib/plugins/baseldap.py:1527:80: E501 line too long (81  79 
characters)

./ipalib/plugins/user.py:915:80: E501 line too long (80  79 characters)

as well as many errors in the files this patch adds.


2) Pylint reports the following error:

ipatests/test_xmlrpc/test_vault_plugin.py:153: 
[E0102(function-redefined), test_vault] class already defined line 27)



3) The container_vault config option should be renamed to 
container_vaultcontainer, as it is used in the vaultcontainer plugin, 
not the vault plugin.



4) The vault object should be child of the vaultcontainer object.

Not only is this correct from the object model perspective, but it would 
also make all the container_id hacks go away.



5) When specifying param flags, use set literals.

This is especially wrong, because it's not a tuple, but a string in 
parentheses:


+flags=('virtual_attribute'),


6) The `container` param of vault should actually be an option in 
vault_* commands.


Also it should be renamed to `container_id`, for consistency with 
vaultcontainer.



7) The `vault_id` param of vault should have no_option in flags, since 
it is output-only.



8) Don't translate docstrings where not necessary:

+def get_dn(self, *keys, **options):
+__doc__ = _(
+Generates vault DN from vault ID.
+)

Only plugin modules and classes should have translated docstrings.


9) This looks wrong in vault.get_dn() and vaultcontainer.get_dn():

+name = None
+if keys:
+name = keys[0]

Primary key of the object should always be set, so the if statement 
should not be there.


Also, primary key of any given object is always last in keys, so use 
keys[-1] instead of keys[0].



10) Use self.api instead of api to access the API in plugins.


11) No clever optimizations like this please:

+# vault DN cannot be the container base DN
+if len(dn) == len(api.Object.vaultcontainer.base_dn):
+raise ValueError('Invalid vault DN: %s' % dn)

Compare the DNs by value instead.


12) vault.split_id() is not used anywhere.


13) Bytes is not base64-encoded data:

+Bytes('data?',
+cli_name='data',
+doc=_('Base-64 encoded binary data to archive'),
+),

It is base64-encoded in the CLI, but on the API level it is not. The doc 
should say just Binary data to archive.



14) Use File instead of Str for input files:

+Str('in?',
+cli_name='in',
+doc=_('File containing data to archive'),
+),


15) Use MutuallyExclusiveError instead of ValidationError when there are 
mutually exclusive options specified.



16) You do way too much stuff in vault_add.forward(). Only code that 
must be done on the client needs to be there, i.e. handling of the 
data, text and in options.


The vault_archive call must be in vault_add.execute(), otherwise a) we 
will be making 2 RPC calls from the client and b) it won't be called at 
all when api.env.in_server is True.



17) Why are vaultcontainer objects automatically created in vault_add?

If you have to automatically create them, you also have to automatically 
delete them when the command fails. But that's a hassle, so I would just 
not create them automatically.



18) Why are vaultcontainer objects automatically created in vault_find?

This is just plain wrong and has to be removed, now.


19) What is the reason behind all the json stuff in vault_transport_cert?

vault_transport_cert.__json__() is exactly the same as 
Command.__json__() and hence redundant.



20) Are vault_transport_cert, vault_archive and vault_retrieve supposed 
to be runnable by users? If not, add NO_CLI = True to the class 
definition.



21) vault_archive is not a retrieve operation, it should be based on 
LDAPUpdate instead of LDAPRetrieve. Or Command actually, since it does 
not do anything with LDAP. The same applies to vault_retrieve.



22) vault_archive will break with binary data that is not UTF-8 encoded 
text.


This is where it occurs:

+vault_data[u'data'] = unicode(data)

Generally, don't use unicode() on str values and str() on unicode values 
directly, always use .decode() and .encode().



23) Since vault containers are nested, the vaultcontainer object should 
be child of itself.


There is no support for nested objects in the framework, but it 
shouldn't be too hard to do