From 4bd1be9e90ea7369edb4ae15ff8c51232d5ab850 Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Mon, 5 Sep 2022 15:37:49 +0200 Subject: [PATCH] API: add new commands for ipa passkeyconfig-show | mod Currently supports a single parameter: --require-user-verification [ 'on', 'off', 'default'] Related: https://pagure.io/freeipa/issue/9261 Signed-off-by: Florence Blanc-Renaud Reviewed-By: Alexander Bokovoy --- ACI.txt | 4 ++ API.txt | 25 ++++++++ VERSION.m4 | 4 +- doc/api/commands.rst | 2 + doc/api/passkeyconfig_mod.md | 34 +++++++++++ doc/api/passkeyconfig_show.md | 29 +++++++++ install/updates/73-passkey.update | 14 +++++ install/updates/Makefile.am | 1 + ipalib/constants.py | 1 + ipaserver/plugins/passkeyconfig.py | 95 ++++++++++++++++++++++++++++++ pylint_plugins.py | 1 + 11 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 doc/api/passkeyconfig_mod.md create mode 100644 doc/api/passkeyconfig_show.md create mode 100644 install/updates/73-passkey.update create mode 100644 ipaserver/plugins/passkeyconfig.py diff --git a/ACI.txt b/ACI.txt index f00901375..62ff5ea7c 100644 --- a/ACI.txt +++ b/ACI.txt @@ -224,6 +224,10 @@ dn: cn=ng,cn=alt,dc=ipa,dc=example aci: (targetfilter = "(objectclass=ipanisnetgroup)")(version 3.0;acl "permission:System: Remove Netgroups";allow (delete) groupdn = "ldap:///cn=System: Remove Netgroups,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: cn=otp,cn=etc,dc=ipa,dc=example aci: (targetattr = "cn || ipatokenhotpauthwindow || ipatokenhotpsyncwindow || ipatokentotpauthwindow || ipatokentotpsyncwindow")(targetfilter = "(objectclass=ipatokenotpconfig)")(version 3.0;acl "permission:System: Read OTP Configuration";allow (compare,read,search) userdn = "ldap:///all";) +dn: cn=passkeyconfig,cn=etc,dc=ipa,dc=example +aci: (targetattr = "iparequireuserverification")(targetfilter = "(objectclass=ipapasskeyconfigobject)")(version 3.0;acl "permission:System: Modify Passkey Configuration";allow (write) groupdn = "ldap:///cn=System: Modify Passkey Configuration,cn=permissions,cn=pbac,dc=ipa,dc=example";) +dn: cn=passkeyconfig,cn=etc,dc=ipa,dc=example +aci: (targetattr = "cn || iparequireuserverification")(targetfilter = "(objectclass=ipapasskeyconfigobject)")(version 3.0;acl "permission:System: Read Passkey Configuration";allow (compare,read,search) userdn = "ldap:///all";) dn: cn=permissions,cn=pbac,dc=ipa,dc=example aci: (targetattr = "member")(targetfilter = "(objectclass=ipapermission)")(version 3.0;acl "permission:System: Modify Privilege Membership";allow (write) groupdn = "ldap:///cn=System: Modify Privilege Membership,cn=permissions,cn=pbac,dc=ipa,dc=example";) dn: dc=ipa,dc=example diff --git a/API.txt b/API.txt index 0fc975947..78d655a00 100644 --- a/API.txt +++ b/API.txt @@ -3819,6 +3819,28 @@ option: Str('version?') output: Entry('result') output: Output('summary', type=[, ]) output: PrimaryKey('value') +command: passkeyconfig_mod/1 +args: 0,8,3 +option: Str('addattr*', cli_name='addattr') +option: Flag('all', autofill=True, cli_name='all', default=False) +option: Str('delattr*', cli_name='delattr') +option: StrEnum('iparequireuserverification?', autofill=False, cli_name='require_user_verification', values=[u'on', u'off', u'default']) +option: Flag('raw', autofill=True, cli_name='raw', default=False) +option: Flag('rights', autofill=True, default=False) +option: Str('setattr*', cli_name='setattr') +option: Str('version?') +output: Entry('result') +output: Output('summary', type=[, ]) +output: PrimaryKey('value') +command: passkeyconfig_show/1 +args: 0,4,3 +option: Flag('all', autofill=True, cli_name='all', default=False) +option: Flag('raw', autofill=True, cli_name='raw', default=False) +option: Flag('rights', autofill=True, default=False) +option: Str('version?') +output: Entry('result') +output: Output('summary', type=[, ]) +output: PrimaryKey('value') command: passwd/1 args: 3,2,3 arg: Principal('principal', autofill=True, cli_name='user') @@ -7295,6 +7317,9 @@ default: output_show/1 default: param/1 default: param_find/1 default: param_show/1 +default: passkeyconfig/1 +default: passkeyconfig_mod/1 +default: passkeyconfig_show/1 default: passwd/1 default: permission/1 default: permission_add/1 diff --git a/VERSION.m4 b/VERSION.m4 index 6b4b321d1..0685ae0ca 100644 --- a/VERSION.m4 +++ b/VERSION.m4 @@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000) # # ######################################################## define(IPA_API_VERSION_MAJOR, 2) -# Last change: RBCD implementation -define(IPA_API_VERSION_MINOR, 252) +# Last change: add passkey support +define(IPA_API_VERSION_MINOR, 253) ######################################################## # Following values are auto-generated from values above diff --git a/doc/api/commands.rst b/doc/api/commands.rst index 85259bd5f..f31837551 100644 --- a/doc/api/commands.rst +++ b/doc/api/commands.rst @@ -271,6 +271,8 @@ IPA API Commands output_show.md param_find.md param_show.md + passkeyconfig_mod.md + passkeyconfig_show.md passwd.md permission_add.md permission_add_member.md diff --git a/doc/api/passkeyconfig_mod.md b/doc/api/passkeyconfig_mod.md new file mode 100644 index 000000000..2e92a5c95 --- /dev/null +++ b/doc/api/passkeyconfig_mod.md @@ -0,0 +1,34 @@ +[//]: # (THE CONTENT BELOW IS GENERATED. DO NOT EDIT.) +# passkeyconfig_mod +Modify Passkey configuration. + +### Arguments +No arguments. + +### Options +* rights : :ref:`Flag` **(Required)** + * Default: False +* all : :ref:`Flag` **(Required)** + * Default: False +* raw : :ref:`Flag` **(Required)** + * Default: False +* iparequireuserverification : :ref:`StrEnum` + * Values: ('on', 'off', 'default') +* setattr : :ref:`Str` +* addattr : :ref:`Str` +* delattr : :ref:`Str` +* version : :ref:`Str` + +### Output +|Name|Type +|-|- +|result|Entry +|summary|Output +|value|PrimaryKey + +[//]: # (ADD YOUR NOTES BELOW. THESE WILL BE PICKED EVERY TIME THE DOCS ARE REGENERATED. //end) +### Semantics + +### Notes + +### Version differences \ No newline at end of file diff --git a/doc/api/passkeyconfig_show.md b/doc/api/passkeyconfig_show.md new file mode 100644 index 000000000..b4ff41269 --- /dev/null +++ b/doc/api/passkeyconfig_show.md @@ -0,0 +1,29 @@ +[//]: # (THE CONTENT BELOW IS GENERATED. DO NOT EDIT.) +# passkeyconfig_show +Show the current Passkey configuration. + +### Arguments +No arguments. + +### Options +* rights : :ref:`Flag` **(Required)** + * Default: False +* all : :ref:`Flag` **(Required)** + * Default: False +* raw : :ref:`Flag` **(Required)** + * Default: False +* version : :ref:`Str` + +### Output +|Name|Type +|-|- +|result|Entry +|summary|Output +|value|PrimaryKey + +[//]: # (ADD YOUR NOTES BELOW. THESE WILL BE PICKED EVERY TIME THE DOCS ARE REGENERATED. //end) +### Semantics + +### Notes + +### Version differences \ No newline at end of file diff --git a/install/updates/73-passkey.update b/install/updates/73-passkey.update new file mode 100644 index 000000000..26d8c0c5f --- /dev/null +++ b/install/updates/73-passkey.update @@ -0,0 +1,14 @@ +# Configuration for Passkey Authentication +dn: cn=passkeyconfig,cn=etc,$SUFFIX +default:objectclass: top +default:objectclass: nscontainer +default:objectclass: ipaPasskeyConfigObject +default:ipaRequireUserVerification: default + +# Passkey Administrators +dn: cn=Passkey Administrators,cn=privileges,cn=pbac,$SUFFIX +default:objectClass: top +default:objectClass: groupofnames +default:objectClass: nestedgroup +default:cn: Passkey Administrators +default:description: Passkey Administrators diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am index 43a3c11b6..fbc1b76ae 100644 --- a/install/updates/Makefile.am +++ b/install/updates/Makefile.am @@ -66,6 +66,7 @@ app_DATA = \ 73-subid.update \ 73-winsync.update \ 73-certmap.update \ + 73-passkey.update \ 75-user-trust-attributes.update \ 80-schema_compat.update \ 81-externalmembers.update \ diff --git a/ipalib/constants.py b/ipalib/constants.py index 104419bc2..ee3e85aa2 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -156,6 +156,7 @@ DEFAULT_CONFIG = ( DN(('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'))), ('container_subids', DN(('cn', 'subids'), ('cn', 'accounts'))), ('container_idp', DN(('cn', 'idp'))), + ('container_passkey', DN(('cn', 'passkeyconfig'), ('cn', 'etc'))), # Ports, hosts, and URIs: # Following values do not have any reasonable default. diff --git a/ipaserver/plugins/passkeyconfig.py b/ipaserver/plugins/passkeyconfig.py new file mode 100644 index 000000000..9ba36dd3a --- /dev/null +++ b/ipaserver/plugins/passkeyconfig.py @@ -0,0 +1,95 @@ +# +# Copyright (C) 2022 FreeIPA Contributors see COPYING for license +# + +import logging + +from ipalib import api +from ipalib.parameters import StrEnum +from ipalib.plugable import Registry +from .baseldap import ( + LDAPObject, + LDAPRetrieve, + LDAPUpdate) +from ipalib import _ + + +logger = logging.getLogger(__name__) + +__doc__ = _(""" +Passkey configuration +""") + _(""" +Manage Passkey configuration. +""") + _(""" +IPA supports the use of passkeys for authentication. A passkey +device has to be registered to SSSD and the resulting authentication mapping +stored in the user entry. +The passkey authentication supports the following configuration option: +require user verification. When set, the method for user verification depends +on the type of device (PIN, fingerprint, external pad...) +""") + _(""" +EXAMPLES: +""") + _(""" + Display the Passkey configuration: + ipa passkeyconfig-show +""") + _(""" + Modify the Passkey configuration to always require user verification: + ipa passkeyconfig-mod --require-user-verification=on +""") + +register = Registry() + + +@register() +class passkeyconfig(LDAPObject): + """ + Passkey configuration object + """ + object_name = _('Passkey configuration options') + default_attributes = ['iparequireuserverification'] + + container_dn = api.env.container_passkey + label = _('Passkey Configuration') + label_singular = _('Passkey Configuration') + + takes_params = ( + StrEnum( + 'iparequireuserverification', + cli_name="require_user_verification", + label=_("Require user verification"), + doc=_('Require user verification during authentication'), + values=('on', 'off', 'default'), + ), + ) + + permission_filter_objectclasses = ['ipapasskeyconfigobject'] + managed_permissions = { + 'System: Read Passkey Configuration': { + 'replaces_global_anonymous_aci': True, + 'ipapermbindruletype': 'all', + 'ipapermright': {'read', 'search', 'compare'}, + 'ipapermdefaultattr': { + 'iparequireuserverification', + 'cn', + }, + }, + 'System: Modify Passkey Configuration': { + 'replaces_global_anonymous_aci': True, + 'ipapermright': {'write'}, + 'ipapermdefaultattr': { + 'iparequireuserverification', + }, + 'default_privileges': { + 'Passkey Administrators'}, + }, + } + + +@register() +class passkeyconfig_mod(LDAPUpdate): + __doc__ = _("Modify Passkey configuration.") + + +@register() +class passkeyconfig_show(LDAPRetrieve): + __doc__ = _("Show the current Passkey configuration.") diff --git a/pylint_plugins.py b/pylint_plugins.py index c352e2e4a..1418400aa 100644 --- a/pylint_plugins.py +++ b/pylint_plugins.py @@ -419,6 +419,7 @@ AstroidBuilder(MANAGER).string_build(textwrap.dedent( api.env.container_dna_posix_ids = DN() api.env.container_dns = DN() api.env.container_dnsservers = DN() + api.env.container_passkey = DN() api.env.container_group = DN() api.env.container_hbac = DN() api.env.container_hbacservice = DN()