diff options
-rw-r--r-- | .travis.yml | 16 | ||||
-rw-r--r-- | NEWS | 37 | ||||
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | TODO | 373 | ||||
-rwxr-xr-x | contrib/wallet-contacts | 4 | ||||
-rw-r--r-- | docs/design-acl | 34 | ||||
-rw-r--r-- | perl/lib/Wallet/ACL/External.pm | 198 | ||||
-rw-r--r-- | perl/lib/Wallet/Config.pm | 35 | ||||
-rw-r--r-- | perl/lib/Wallet/Kadmin/MIT.pm | 5 | ||||
-rw-r--r-- | perl/lib/Wallet/Object/Duo.pm | 34 | ||||
-rwxr-xr-x | perl/t/data/acl-command | 43 | ||||
-rwxr-xr-x | perl/t/object/keytab.t | 26 | ||||
-rw-r--r-- | perl/t/object/password.t | 1 | ||||
-rwxr-xr-x | perl/t/verifier/external.t | 32 | ||||
-rwxr-xr-x | server/wallet-report | 24 |
15 files changed, 637 insertions, 230 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..3f60b23 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +sudo: required +dist: trusty + +language: c +compiler: + - gcc + +before_install: + - sudo apt-get update -qq + - sudo apt-get install -y libauthen-sasl-perl libcrypt-generatepassword-perl libdatetime-perl libdatetime-format-sqlite-perl libdbd-sqlite3-perl libdbi-perl libdbix-class-perl libheimdal-kadm5-perl libjson-perl libkrb5-dev libnet-dns-perl libnet-ldap-perl libnet-remctl-perl libperl6-slurp-perl libremctl-dev libsql-translator-perl libtest-minimumversion-perl libtest-pod-perl libtest-strict-perl libtimedate-perl libwebauth-perl perl sqlite3 +env: AUTHOR_TESTING=1 +script: ./autogen && ./configure && make warnings && make check + +branches: + only: + - master @@ -2,10 +2,33 @@ wallet 1.3 (unreleased) + A new ACL type, nested (Wallet::ACL::Nested), is now supported. The + identifier of this ACL names another ACL, and access is granted if + that ACL would grant access. This lets one combine multiple other + ACLs and apply the union to an object. To enable this ACL type for an + existing wallet database, use wallet-admin to register the new + verifier. + + A new ACL type, external (Wallet::ACL::External), is now supported. + This ACL runs an external command to check if access is allowed, and + passes the principal and the ACL identifier to that command. To + enable this ACL type for an existing wallet database, use wallet-admin + to register the new verifier. + + A new variation on the ldap-attr ACL type, ldap-attr-root + (Wallet::ACL::LDAP::Attribute::Root), is now supported. This is + similar to netdb-root (compared to netdb): the authenticated principal + must end in /root, and the LDAP entry checked will be for the same + principal without the /root component. This is useful for limiting + access to certain privileged objects to Kerberos root instances. To + enable this ACL type for an existing wallet database, use wallet-admin + to register the new verifier. + A new object type, password (Wallet::Object::Password), is now supported. This is a subclass of the file object that will randomly generate content for the object if you do a get before storing any - content inside it. + content inside it. To enable this object type for an existing + database, use wallet-admin to register the new object. Add a new command to wallet-backend, update. This will update the contents of an object before running a get on it, and is only valid @@ -17,7 +40,8 @@ wallet 1.3 (unreleased) warrants. Add an acl replace command, to change all objects owned by one ACL to - be owned by another. + be owned by another. This currently only handles owner, not any of + the more specific ACLs. All ACL operations now refer to the ACL by name rather than ID. @@ -25,11 +49,20 @@ wallet 1.3 (unreleased) help for the existing unused report that implied it showed unstored as well as unused. + Add reports that list all object types (types) and all ACL schemes + (schemes) currently registered in the wallet database. + + Add a report of all ACLs that nest a given ACL. This requires some + additional local configuration (and probably some code). See + Wallet::Config for more information. + Took contributions from Commerzbank AG to improve wallet history. Add a command to dump all object history for searching on to wallet-report, and add a new script for more detailed object history operations to the contrib directory. + Displays of ACLs and ACL entries are now sorted correctly. + Initial support for using Active Directory as the KDC for keytab creation. The interface to Active Directory uses a combination of direct LDAP queries and the msktutil utility. This version does @@ -109,7 +109,10 @@ REQUIREMENTS WebAuth Perl module from WebAuth 4.4.0 or later. The Duo integration object support in the wallet server requires the - Net::Duo Perl module. + Net::Duo, JSON, and Perl6::Slurp Perl modules. + + The password object support in the wallet server requires the + Crypt::GeneratePassword Perl module. To support the LDAP attribute ACL verifier, the Authen::SASL and Net::LDAP Perl modules must be installed on the server. This verifier @@ -2,290 +2,265 @@ Client: - * KERB-94: Handle duplicate kvnos in a newly returned keytab and an - existing keytab (such as when downloading an unchanging keytab and - merging it into an existing one) in some reasonable fashion. + * Handle duplicate kvnos in a newly returned keytab and an existing + keytab (such as when downloading an unchanging keytab and merging it + into an existing one) in some reasonable fashion. - * KERB-90: Support removing old kvnos from a merged keytab (similar to - kadmin ktremove old). + * Support removing old kvnos from a merged keytab (similar to kadmin + ktremove old). - * KERB-88: When reading configuration from krb5.conf, we should first try - to determine our principal from any existing Kerberos ticket cache - (after obtaining tickets if -u was given) and extract the realm from - that principal, using it as the default realm when reading - configuration information. + * When reading configuration from krb5.conf, we should first try to + determine our principal from any existing Kerberos ticket cache (after + obtaining tickets if -u was given) and extract the realm from that + principal, using it as the default realm when reading configuration + information. - * KERB-89: Add readline support to the wallet client to make it easier to - issue multiple commands. + * Add readline support to the wallet client to make it easier to issue + multiple commands. - * KERB-115: Support authenticating with a keytab. + * Support authenticating with a keytab. - * KERB-97: When obtaining tickets in the wallet client with -u, directly - obtain the service ticket we're going to use for remctl. + * When obtaining tickets in the wallet client with -u, directly obtain + the service ticket we're going to use for remctl. - * KERB-95: Provide a way to refresh a file object if and only if what's - stored on the server is different than what's on disk. This will - require server support as well for returning the checksum of a file. + * Provide a way to refresh a file object if and only if what's stored on + the server is different than what's on disk. This will require server + support as well for returning the checksum of a file. - * KERB-104: Incorporate the wallet-rekey-periodic script (currently in - contrib) into the package and teach it how to ignore foreign - credentials. + * Incorporate the wallet-rekey-periodic script (currently in contrib) + into the package and teach it how to ignore foreign credentials. Server Interface: - * KERB-126: Provide a way to get history for deleted objects and ACLs. + * Provide a way to get history for deleted objects and ACLs. - * KERB-66: Provide an interface to mass-change all instances of one ACL - to another. + * Provide an interface to mass-change all instances of one ACL to + another. (Owner changes are currently supported, but not the other + ACLs.) - * KERB-96: Add help functions to wallet-backend, wallet-report, and - wallet-admin listing the commands. + * Add help functions to wallet-backend and wallet-admin listing the + commands. - * KERB-52: Catch exceptions on object creation in wallet-backend so that - we can log those as well. + * Catch exceptions on object creation in wallet-backend so that we can + log those as well. - * KERB-114: Provide a way to list all objects for which the connecting - user has ACLs. + * Provide a way to list all objects for which the connecting user has + ACLs. - * KERB-101: Support limiting returned history information by timestamp. + * Support limiting returned history information by timestamp. - * KERB-128: Provide a REST implementation of the wallet server. + * Provide a REST implementation of the wallet server. - * KERB-79: Provide a CGI implementation of the wallet server. + * Provide a CGI implementation of the wallet server. - * KERB-111: Support setting flags and attributes on autocreate. In - general, work out a Wallet::Object::Template Perl object that I can - return that specifies things other than just the ACL. + * Support setting flags and attributes on autocreate. In general, work + out a Wallet::Object::Template Perl object that I can return that + specifies things other than just the ACL. - * KERB-93: Remove the hard-coded ADMIN ACL in the server with something - more configurable, perhaps a global ACL table or something. + * Remove the hard-coded ADMIN ACL in the server with something more + configurable, perhaps a global ACL table or something. - * KERB-68: Support leap-of-faith keying of systems by registering an - object for one-time download (ideally from a specific IP address) and - then allowing that object to be downloaded anonymously from that IP. - Relies on support for Kerberos anonymous authentication. + * Support leap-of-faith keying of systems by registering an object for + one-time download (ideally from a specific IP address) and then + allowing that object to be downloaded anonymously from that IP. Relies + on support for Kerberos anonymous authentication. - * KERB-84: Split "get" and "update" in semantics, and only do keytab - rekeying on update. "get" would not be permitted unless the keytab was - flagged as unchanging, and update would still change even an unchanging - keytab (maybe). Or, alternately, maybe we allow get of any keytab? - Requires more thought. + * Split "get" and "update" in semantics, and only do keytab rekeying on + update. "get" would not be permitted unless the keytab was flagged as + unchanging, and update would still change even an unchanging keytab + (maybe). Or, alternately, maybe we allow get of any keytab? Requires + more thought. - * KERB-118: Add command to list available types and schemes. + * Add a mechanism to automate owner updates based on default_owner. - * KERB-75: Add a mechanism to automate owner updates based on - default_owner. + * Partially merge create and autocreate. create and autocreate should do + the same thing provided there is an autocreation configuration + available. If not, autocreate should fail and create should fall back + on checking for ADMIN privileges. - * KERB-64: Partially merge create and autocreate. create and autocreate - should do the same thing provided there is an autocreation - configuration available. If not, autocreate should fail and create - should fall back on checking for ADMIN privileges. + * Rewrite server backends to use Net::Remctl::Backend. - * KERB-116: Support file object renaming. + * Merge the Wallet::Logger support written by Commerzbank AG: create a + new class that handles logging, probably based on Log::Log4perl, and + add logging points to all of the core classes. - * KERB-131: Rewrite server backends to use Net::Remctl::Backend. - - * KERB-132: Merge the Wallet::Logger support written by Commerzbank AG: - create a new class that handles logging, probably based on - Log::Log4perl, and add logging points to all of the core classes. - - * KERB-133: Support an authorization hook to determine whether or not to - permit autocreate. One requested example feature is to limit - autocreate of keytab objects to certain hosts involved in deployment. - It should be possible to write a hook that takes the information about - what object is being autocreated and can accept or decline. + * Support an authorization hook to determine whether or not to permit + autocreate. One requested example feature is to limit autocreate of + keytab objects to certain hosts involved in deployment. It should be + possible to write a hook that takes the information about what object + is being autocreated and can accept or decline. ACLs: - * KERB-119: Error messages from ACL operations should refer to the ACLs - by name instead of by ID. - - * KERB-121: Write the PTS ACL verifier. + * Error messages from ACL operations should refer to the ACLs by name + instead of by ID. - * KERB-123: Rename Wallet::ACL::* to Wallet::Verifier::*. Add - Wallet::ACL as a generic interface with Wallet::ACL::Database and - Wallet::ACL::List implementations (or some similar name) so that we can - create and check an ACL without having to write it into the database. - Redo default ACL creation using that functionality. + * Write the PTS ACL verifier. - * KERB-67: Pass a reference to the object for which the ACL is - interpreted to the ACL API so that ACL APIs can make more complex - decisions. + * Rename Wallet::ACL::* to Wallet::Verifier::*. Add Wallet::ACL as a + generic interface with Wallet::ACL::Database and Wallet::ACL::List + implementations (or some similar name) so that we can create and check + an ACL without having to write it into the database. Redo default ACL + creation using that functionality. - * KERB-109: A group-in-groups ACL schema. + * Pass a reference to the object for which the ACL is interpreted to the + ACL API so that ACL APIs can make more complex decisions. - * KERB-113: Provide an API for verifiers to syntax-check the values - before an ACL is set and implement syntax checking for the krb5 and - ldap-attr verifiers. + * Provide an API for verifiers to syntax-check the values before an ACL + is set and implement syntax checking for the krb5 and ldap-attr + verifiers. - * KERB-60: Investigate how best to support client authentication using - anonymous PKINIT for things like initial system keying. + * Investigate how best to support client authentication using anonymous + PKINIT for things like initial system keying. - * KERB-72: Generalize the current NetDB ACL type to allow a generic - remctl query for whether a particular user is authorized to create - host-based objects for a particular host. + * Generalize the current NetDB ACL type to allow a generic remctl query + for whether a particular user is authorized to create host-based + objects for a particular host. - * KERB-78: Add ldap-group ACL scheme. + * Add ldap-group ACL scheme (and possibly a root-only version). - * KERB-63: Provide a root-instance version of the ldap-attr (and possibly - the ldap-group) ACL schemes. + * Add a comment field to ACLs. - * KERB-86: Add a comment field to ACLs. + * Support external ACLs under a backend other than remctl. This will + require some way of re-exporting the authenticated user identity + instead of relying on the existence of the remctl variables. Database: - * KERB-55: Fix case-insensitivity bug in unique keys with MySQL for - objects. When creating an http/<host> principal when an HTTP/<host> - principal already existed, MySQL rejected the row entry as a duplicate. - The name should be case-sensitive. + * Fix case-insensitivity bug in unique keys with MySQL for objects. When + creating an http/<host> principal when an HTTP/<host> principal already + existed, MySQL rejected the row entry as a duplicate. The name should + be case-sensitive. - * KERB-103: On upgrades, support adding new object types and ACL - verifiers to the class tables. + * On upgrades, support adding new object types and ACL verifiers to the + class tables. Objects: - * KERB-120: Check whether we can just drop the realm restriction on - keytabs and allow the name to contain the realm if the Kerberos type is - Heimdal. + * Check whether we can just drop the realm restriction on keytabs and + allow the name to contain the realm if the Kerberos type is Heimdal. - * KERB-59: Use the Perl Authen::Krb5::Admin module instead of rolling our - own kadmin code with Expect now that MIT Kerberos has made the kadmin - API public. + * Use the Perl Authen::Krb5::Admin module instead of rolling our own + kadmin code with Expect now that MIT Kerberos has made the kadmin API + public. - * KERB-85: Implement an ssh keypair wallet object. The server can run - ssh-keygen to generate a public/private key pair and return both to the - client, which would split them apart. Used primarily for host keys. - May need a side table to store key types, or a naming convention. + * Implement an ssh keypair wallet object. The server can run ssh-keygen + to generate a public/private key pair and return both to the client, + which would split them apart. Used primarily for host keys. May need + a side table to store key types, or a naming convention. - * KERB-124: Implement an X.509 certificate object. I expect this would - store the public and private key as a single file in the same format - that Apache can read for combined public and private keys. There were - requests for storing the CSR, but I don't see why you'd want to do - that. Start with store support. The file code is mostly sufficient - here, but it would be nice to automatically support object expiration - based on the expiration time for the certificate. + * Implement an X.509 certificate object. I expect this would store the + public and private key as a single file in the same format that Apache + can read for combined public and private keys. There were requests for + storing the CSR, but I don't see why you'd want to do that. Start with + store support. The file code is mostly sufficient here, but it would + be nice to automatically support object expiration based on the + expiration time for the certificate. - * KERB-106: Implement an X.509 CA so that you can get certificate objects - without storing them first. Need to resolve naming conventions if you - want to run multiple CAs on the same wallet server (but why?). Should - this be a different type than stored certificates? Consider using - hxtool as the underlying CA mechanism. + * Implement an X.509 CA so that you can get certificate objects without + storing them first. Need to resolve naming conventions if you want to + run multiple CAs on the same wallet server (but why?). Should this be + a different type than stored certificates? Consider using hxtool as + the underlying CA mechanism. - * KERB-77: Support returning the checksum of a file object stored in - wallet so that one can determine whether the version stored on disk is - identical. + * Support returning the checksum of a file object stored in wallet so + that one can determine whether the version stored on disk is identical. - * KERB-108: Implement new password wallet object, which is like file - except that it generates a random, strong password when retrieved the - first time without being stored. - - * KERB-71: Support interrogating objects to find all host-based objects - for a particular host, allowing cleanup of all of those host's objects - after retiring the host. - - * KERB-127: Support setting the disallow-svr flag on created principals. - In general, support setting arbitrary principal flags. + * Support setting the disallow-svr flag on created principals. In + general, support setting arbitrary principal flags. Reports: - * KERB-117: Add audit for references to unknown ACLs, possibly introduced - by previous versions before ACL deletion was checked with database + * Add audit for references to unknown ACLs, possibly introduced by + previous versions before ACL deletion was checked with database backends that don't do referential integrity. - * KERB-105: Add report for all objects that have never been stored. - - * KERB-122: For objects tied to hostnames, report on objects referring to - hosts which do not exist. For the initial pass, this is probably only - keytab objects with names containing a slash where the part after the - slash looks like a hostname. This may need some configuration help. + * For objects tied to hostnames, report on objects referring to hosts + which do not exist. For the initial pass, this is probably only keytab + objects with names containing a slash where the part after the slash + looks like a hostname. This may need some configuration help. - * KERB-102: Make contrib/wallet-summary generic and include it in - wallet-report, with additional configuration in Wallet::Config. - Enhance it to report on any sort of object, not just on keytabs, and to - give numbers on downloaded versus not downloaded objects. + * Make contrib/wallet-summary generic and include it in wallet-report, + with additional configuration in Wallet::Config. Enhance it to report + on any sort of object, not just on keytabs, and to give numbers on + downloaded versus not downloaded objects. - * KERB-69: Write a tool to mail the owners of wallet objects, taking the - list of objects and the mail message to send as inputs. This could - possibly use the notification service, although a version that sends - mail directly would be useful external to Stanford. + * Write a tool to mail the owners of wallet objects, taking the list of + objects and the mail message to send as inputs. This could possibly + use the notification service, although a version that sends mail + directly would be useful external to Stanford. - * KERB-134: Merge the Commerzbank AG work to dump all the object history, - applying various search criteria to it, or clear parts of the object - history. + * Merge the Commerzbank AG work to dump all the object history, applying + various search criteria to it, or clear parts of the object history. Administrative Interface: - * KERB-80: Add a function to wallet-admin to purge expired entries. - Possibly also check expiration before allowing anyone to get or store - objects. + * Add a function to wallet-admin to purge expired entries. Possibly also + check expiration before allowing anyone to get or store objects. - * KERB-58: Add a function or separate script to automate removal of - DNS-based objects for which the hosts no longer exist. Will need to - support a site-specific callout to determine whether the host exists. + * Add a function or separate script to automate removal of DNS-based + objects for which the hosts no longer exist. Will need to support a + site-specific callout to determine whether the host exists. - * KERB-54: Database creation appears not to work without the SQL files, - but it's supposed to work directly from the classes. Double-check - this. + * Database creation appears not to work without the SQL files, but it's + supposed to work directly from the classes. Double-check this. Documentation: - * KERB-82: Write a conventions document for ACL naming, object naming, - and similar issues. + * Write a conventions document for ACL naming, object naming, and similar + issues. - * KERB-125: Write a future design and roadmap document to collect notes - about how unimplemented features should be handled. + * Write a future design and roadmap document to collect notes about how + unimplemented features should be handled. - * KERB-65: Document using the wallet system over something other than - remctl. + * Document using the wallet system over something other than remctl. - * KERB-112: Document all diagnostics for all wallet APIs. + * Document all diagnostics for all wallet APIs. - * KERB-135: Document configuration with an Oracle database. + * Document configuration with an Oracle database. Code Style and Cleanup: - * KERB-98: There is a lot of duplicate code in wallet-backend. Convert - that to use some sort of data-driven model with argument count and - flags so that the method calls can be written only once. Convert - wallet-admin to use the same code. + * There is a lot of duplicate code in wallet-backend. Convert that to + use some sort of data-driven model with argument count and flags so + that the method calls can be written only once. Convert wallet-admin + to use the same code. - * KERB-100: There's a lot of code duplication in the dispatch functions - in the Wallet::Server class. Find a way to rewrite that so that the - dispatch doesn't duplicate the same code patterns. + * There's a lot of code duplication in the dispatch functions in the + Wallet::Server class. Find a way to rewrite that so that the dispatch + doesn't duplicate the same code patterns. - * KERB-73: The wallet-backend and wallet documentation share the COMMANDS - section. Work out some means to assemble the documentation without - duplicating content. + * The wallet-backend and wallet documentation share the COMMANDS section. + Work out some means to assemble the documentation without duplicating + content. - * KERB-110: The Wallet::Config class is very ugly and could use some - better internal API to reference the variables in it. + * The Wallet::Config class is very ugly and could use some better + internal API to reference the variables in it. - * KERB-76: Consider using Class::Accessor to get rid of the scaffolding - code to access object data. Alternately, consider using Moose. + * Consider using Class::Accessor to get rid of the scaffolding code to + access object data. Alternately, consider using Moose. - * KERB-130: Rewrite the error handling to use exceptions instead of the - C-style return value and separate error call. + * Rewrite the error handling to use exceptions instead of the C-style + return value and separate error call. Test Suite: - * KERB-92: The ldap-attr verifier test case is awful and completely - specific to people with admin access to the Stanford LDAP tree. Write - a real test. + * The ldap-attr verifier test case is awful and completely specific to + people with admin access to the Stanford LDAP tree. Write a real test. - * KERB-87: Rename the tests to use a subdirectory organization. + * Rename the tests to use a subdirectory organization. - * KERB-61: Add POD coverage testing using Test::POD::Coverage for the - server modules. + * Add POD coverage testing using Test::POD::Coverage for the server + modules. - * KERB-91: Rewrite the client test suite to use Perl and to make better - use of shared code so that it can be broken into function components. + * Rewrite the client test suite to use Perl and to make better use of + shared code so that it can be broken into function components. - * KERB-74: Refactor the test suite for the wallet backend to try to - reduce the duplicated code. Using a real mock infrastructure should - make this test suite much easier to write. + * Refactor the test suite for the wallet backend to try to reduce the + duplicated code. Using a real mock infrastructure should make this + test suite much easier to write. - * KERB-81: Pull common test suite code into a Perl library that can be - reused. + * Pull common test suite code into a Perl library that can be reused. - * KERB-99: Write a test suite to scan all wallet code looking for - diagnostics that aren't in the documentation and warn about them. + * Write a test suite to scan all wallet code looking for diagnostics that + aren't in the documentation and warn about them. diff --git a/contrib/wallet-contacts b/contrib/wallet-contacts index ce16ab1..0c72c9c 100755 --- a/contrib/wallet-contacts +++ b/contrib/wallet-contacts @@ -12,7 +12,7 @@ # Modules and declarations ############################################################################## -use 5.010; +use 5.008; use autodie; use strict; use warnings; @@ -174,7 +174,7 @@ if ($mail) { ############################################################################## =for stopwords -ACL NetDB SQL hostname lookup swhois whois Allbery +ACL NetDB SQL hostname lookup swhois whois Allbery -dryrun =head1 NAME diff --git a/docs/design-acl b/docs/design-acl index 424b3c6..b8bb8b3 100644 --- a/docs/design-acl +++ b/docs/design-acl @@ -13,7 +13,7 @@ Introduction Syntax An ACL entry in the wallet consists of two pieces of data, a <scheme> - and an <instance>. <scheme> is one or more characters in the set + and an <identifier>. <scheme> is one or more characters in the set [a-z0-9-] that identifies the ACL backend to use when interpreting this ACL. <identifier> is zero or more characters including all printable ASCII characters except whitespace. Only the implementation @@ -50,11 +50,35 @@ Semantics ACL Schemes + external + + The <identifier> is arguments to an external command. Access is + granted if the external command returns success. The standard remctl + environment variables are exposed to the external command. + krb5 The <identifier> is a fully-qualified Kerberos principal. Access is granted if the principal of the client matches <identifier>. + ldap-attr + + <identifier> is an an attribute followed by an equal sign and a value. + If the LDAP entry corresponding to the given principal contains the + attribute and value specified by <identifier>, access is granted. + + ldap-attr-root + + This is almost identical to netdb except that the user must be in the + form of a root instance (<user>/root) and the "/root" portion is + stripped before checking the NetDB roles. + + nested + + <identifier> is the name of another ACL, and access is granted if it + is granted by that ACL. This can be used to organize multiple ACLs + into a group and apply their union to an object. + netdb <identifier> is the name of a system. Access is granted if the user @@ -67,13 +91,6 @@ ACL Schemes form of a root instance (<user>/root) and the "/root" portion is stripped before checking the NetDB roles. - ldap-entitlement - - (Not yet implemented.) <identifier> is an entitlement. If the - entitlement attribute of the LDAP entry corresponding to the given - principal contains the entitlement specified in <identifier>, access - is granted. - pts (Not yet implemented.) <identifier> is the name of an AFS PTS group. @@ -82,6 +99,7 @@ ACL Schemes License + Copyright 2016 Russ Allbery <eagle@eyrie.org> Copyright 2006, 2007, 2008, 2013 The Board of Trustees of the Leland Stanford Junior University diff --git a/perl/lib/Wallet/ACL/External.pm b/perl/lib/Wallet/ACL/External.pm new file mode 100644 index 0000000..77c2499 --- /dev/null +++ b/perl/lib/Wallet/ACL/External.pm @@ -0,0 +1,198 @@ +# Wallet::ACL::External -- Wallet external ACL verifier +# +# Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> +# +# See LICENSE for licensing terms. + +############################################################################## +# Modules and declarations +############################################################################## + +package Wallet::ACL::External; +require 5.008; + +use strict; +use warnings; +use vars qw(@ISA $VERSION); + +use POSIX qw(_exit); +use Wallet::ACL::Base; +use Wallet::Config; + +@ISA = qw(Wallet::ACL::Base); + +# This version should be increased on any code change to this module. Always +# use two digits for the minor version with a leading zero if necessary so +# that it will sort properly. +$VERSION = '0.01'; + +############################################################################## +# Interface +############################################################################## + +# Creates a new persistent verifier. This just checks if the configuration +# is in place. +sub new { + my $type = shift; + unless ($Wallet::Config::EXTERNAL_COMMAND) { + die "external ACL support not configured\n"; + } + my $self = {}; + bless ($self, $type); + return $self; +} + +# The most trivial ACL verifier. Returns true if the provided principal +# matches the ACL. +sub check { + my ($self, $principal, $acl) = @_; + unless ($principal) { + $self->error ('no principal specified'); + return; + } + my @args = split (' ', $acl); + unshift @args, $principal; + my $pid = open (EXTERNAL, '-|'); + if (not defined $pid) { + $self->error ("cannot fork: $!"); + return; + } elsif ($pid == 0) { + unless (open (STDERR, '>&STDOUT')) { + warn "wallet: cannot dup stdout: $!\n"; + _exit(1); + } + unless (exec ($Wallet::Config::EXTERNAL_COMMAND, @args)) { + warn "wallet: cannot run $Wallet::Config::EXTERNAL_COMMAND: $!\n"; + _exit(1); + } + } + local $_; + my @output = <EXTERNAL>; + close EXTERNAL; + if ($? == 0) { + return 1; + } else { + if (@output) { + $self->error ($output[0]); + return; + } else { + return 0; + } + } +} + +1; +__END__ + +############################################################################## +# Documentation +############################################################################## + +=for stopwords +ACL Allbery verifier remctl + +=head1 NAME + +Wallet::ACL::External - Wallet ACL verifier using an external command + +=head1 SYNOPSIS + + my $verifier = Wallet::ACL::External->new; + my $status = $verifier->check ($principal, $acl); + if (not defined $status) { + die "Something failed: ", $verifier->error, "\n"; + } elsif ($status) { + print "Access granted\n"; + } else { + print "Access denied\n"; + } + +=head1 DESCRIPTION + +Wallet::ACL::External runs an external command to determine whether access is +granted. The command configured via $EXTERNAL_COMMAND in L<Wallet::Config> +will be run. The first argument to the command will be the principal +requesting access. The identifier of the ACL will be split on whitespace and +passed in as the remaining arguments to this command. + +No other arguments are passed to the command, but the command will have access +to all of the remctl environment variables seen by the wallet server (such as +REMOTE_USER). For a full list of environment variables, see +L<remctld(8)/ENVIRONMENT>. + +The external command should exit with a non-zero status but no output to +indicate a normal failure to satisfy the ACL. Any output will be treated as +an error. + +=head1 METHODS + +=over 4 + +=item new() + +Creates a new ACL verifier. For this verifier, this just confirms that +the wallet configuration sets an external command. + +=item check(PRINCIPAL, ACL) + +Returns true if the external command returns success when run with that +PRINCIPAL and ACL. ACL will be split on whitespace and passed as multiple +arguments. So, for example, the ACL C<external mdbset shell> will, when +triggered by a request from rra@EXAMPLE.COM, result in the command: + + $Wallet::Config::EXTERNAL_COMMAND rra@EXAMPLE.COM mdbset shell + +=item error() + +Returns the error if check() returned undef. + +=back + +=head1 DIAGNOSTICS + +The new() method may fail with one of the following exceptions: + +=over 4 + +=item external ACL support not configured + +The required configuration parameters were not set. See L<Wallet::Config> +for the required configuration parameters and how to set them. + +=back + +Verifying an external ACL may fail with the following errors (returned by +the error() method): + +=over 4 + +=item cannot fork: %s + +The attempt to fork in order to execute the external ACL verifier +command failed, probably due to a lack of system resources. + +=item no principal specified + +The PRINCIPAL parameter to check() was undefined or the empty string. + +=back + +In addition, if the external command fails and produces some output, +that will be considered a failure and the first line of its output will +be returned as the error message. The external command should exit +with a non-zero status but no error to indicate a normal failure. + +=head1 SEE ALSO + +remctld(8), Wallet::ACL(3), Wallet::ACL::Base(3), Wallet::Config(3), +wallet-backend(8) + +This module is part of the wallet system. The current version is +available from L<http://www.eyrie.org/~eagle/software/wallet/>. + +=head1 AUTHOR + +Russ Allbery <eagle@eyrie.org> + +=cut diff --git a/perl/lib/Wallet/Config.pm b/perl/lib/Wallet/Config.pm index b3e1931..98b5dc9 100644 --- a/perl/lib/Wallet/Config.pm +++ b/perl/lib/Wallet/Config.pm @@ -1,7 +1,8 @@ # Wallet::Config -- Configuration handling for the wallet server. # # Written by Russ Allbery <eagle@eyrie.org> -# Copyright 2007, 2008, 2010, 2013, 2014 +# Copyright 2016 Russ Allbery <eagle@eyrie.org> +# Copyright 2007, 2008, 2010, 2013, 2014, 2015 # The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. @@ -16,7 +17,7 @@ use vars qw($PATH $VERSION); # This version should be increased on any code change to this module. Always # use two digits for the minor version with a leading zero if necessary so # that it will sort properly. -$VERSION = '0.05'; +$VERSION = '0.06'; # Path to the config file to load. $PATH = $ENV{WALLET_CONFIG} || '/etc/wallet/wallet.conf'; @@ -540,6 +541,36 @@ our $WAKEYRING_PURGE_INTERVAL = 60 * 60 * 24 * 90; =back +=head1 EXTERNAL ACL CONFIGURATION + +This configuration variable is only needed if you intend to use the +C<external> ACL type (the Wallet::ACL::External class). This ACL type +runs an external command to determine if access is granted. + +=over 4 + +=item EXTERNAL_COMMAND + +Path to the command to run to determine whether access is granted. The +first argument to the command will be the principal requesting access. +The identifier of the ACL will be split on whitespace and passed in as the +remaining arguments to this command. + +No other arguments are passed to the command, but the command will have +access to all of the remctl environment variables seen by the wallet +server (such as REMOTE_USER). For a full list of environment variables, +see L<remctld(8)/ENVIRONMENT>. + +The external command should exit with a non-zero status but no output to +indicate a normal failure to satisfy the ACL. Any output will be treated +as an error. + +=cut + +our $EXTERNAL_COMMAND; + +=back + =head1 LDAP ACL CONFIGURATION These configuration variables are only needed if you intend to use the diff --git a/perl/lib/Wallet/Kadmin/MIT.pm b/perl/lib/Wallet/Kadmin/MIT.pm index ac45265..c5dea23 100644 --- a/perl/lib/Wallet/Kadmin/MIT.pm +++ b/perl/lib/Wallet/Kadmin/MIT.pm @@ -18,6 +18,7 @@ use strict; use warnings; use vars qw(@ISA $VERSION); +use POSIX qw(_exit); use Wallet::Config (); use Wallet::Kadmin (); @@ -65,11 +66,11 @@ sub kadmin { $self->{fork_callback} () if $self->{fork_callback}; unless (open (STDERR, '>&STDOUT')) { warn "wallet: cannot dup stdout: $!\n"; - exit 1; + _exit(1); } unless (exec ($Wallet::Config::KEYTAB_KADMIN, @args)) { warn "wallet: cannot run $Wallet::Config::KEYTAB_KADMIN: $!\n"; - exit 1; + _exit(1); } } local $_; diff --git a/perl/lib/Wallet/Object/Duo.pm b/perl/lib/Wallet/Object/Duo.pm index d0901de..378c123 100644 --- a/perl/lib/Wallet/Object/Duo.pm +++ b/perl/lib/Wallet/Object/Duo.pm @@ -1,7 +1,8 @@ # Wallet::Object::Duo -- Base Duo object implementation for the wallet # # Written by Russ Allbery <eagle@eyrie.org> -# Copyright 2014 +# Copyright 2016 Russ Allbery <eagle@eyrie.org> +# Copyright 2014, 2015 # The Board of Trustees of the Leland Stanford Junior University # # See LICENSE for licensing terms. @@ -18,8 +19,6 @@ use warnings; use vars qw(@ISA $VERSION); use JSON; -use Net::Duo::Admin; -use Net::Duo::Admin::Integration; use Perl6::Slurp qw(slurp); use Wallet::Config (); use Wallet::Object::Base; @@ -159,8 +158,20 @@ sub new { my $key_file = $Wallet::Config::DUO_KEY_FILE; my $agent = $Wallet::Config::DUO_AGENT; + # Check that we can load all of the required modules. + eval { + require Net::Duo; + require Net::Duo::Admin; + require Net::Duo::Admin::Integration; + }; + if ($@) { + my $error = $@; + chomp $error; + 1 while ($error =~ s/ at \S+ line \d+\.?\z//); + die "Duo object support not available: $error\n"; + } + # Construct the Net::Duo::Admin object. - require Net::Duo::Admin; my $duo = Net::Duo::Admin->new ( { key_file => $key_file, @@ -194,8 +205,20 @@ sub create { die "$type is not a valid duo integration\n"; } + # Check that we can load all of the required modules. + eval { + require Net::Duo; + require Net::Duo::Admin; + require Net::Duo::Admin::Integration; + }; + if ($@) { + my $error = $@; + chomp $error; + 1 while ($error =~ s/ at \S+ line \d+\.?\z//); + die "Duo object support not available: $error\n"; + } + # Construct the Net::Duo::Admin object. - require Net::Duo::Admin; my $duo = Net::Duo::Admin->new ( { key_file => $key_file, @@ -204,7 +227,6 @@ sub create { ); # Create the object in Duo. - require Net::Duo::Admin::Integration; my $duo_type = $DUO_TYPES{$type}{integration}; my %data = ( name => "$name ($duo_type)", diff --git a/perl/t/data/acl-command b/perl/t/data/acl-command new file mode 100755 index 0000000..e368118 --- /dev/null +++ b/perl/t/data/acl-command @@ -0,0 +1,43 @@ +#!/bin/sh +# +# An external ACL implementation. Checks that the first argument is +# eagle@eyrie.org, the second argument is "test", and then returns success, +# failure, or reports an error based on whether the second argument is +# success, failure, or error. +# +# Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> +# +# See LICENSE for licensing terms. + +set -e + +# Check the initial principal argument. +if [ "$1" != 'eagle@eyrie.org' ]; then + echo 'incorrect principal' >&2 + exit 1 +fi + +# Check that the second argument is test. +if [ "$2" != 'test' ]; then + echo 'incorrect second argument' >&2 + exit 1 +fi + +# Process the third argument. +case $3 in + success) + exit 0 + ;; + failure) + exit 1 + ;; + error) + echo 'some error' >&2 + exit 1 + ;; + *) + echo 'unknown third argument' >&2 + exit 1 + ;; +esac diff --git a/perl/t/object/keytab.t b/perl/t/object/keytab.t index 69db438..111b7d0 100755 --- a/perl/t/object/keytab.t +++ b/perl/t/object/keytab.t @@ -12,7 +12,7 @@ use strict; use warnings; use POSIX qw(strftime); -use Test::More tests => 141; +use Test::More tests => 142; BEGIN { $Wallet::Config::KEYTAB_TMP = '.' } @@ -25,15 +25,28 @@ use Wallet::Object::Keytab; use lib 't/lib'; use Util; -# Mapping of klist -ke encryption type names to the strings that Kerberos uses -# internally. It's very annoying to have to maintain this, and it probably -# breaks with Heimdal. +# Mapping of klist -ke output from old MIT Kerberos implementations to to the +# strings that Kerberos uses internally. It's very annoying to have to +# maintain this, and it probably breaks with Heimdal. +# +# Newer versions of MIT Kerberos just print out the canonical enctype names +# and don't need this logic, but the current test requires that they still +# have entries. That's why the second set where the key and value are the +# same. my %enctype = ('triple des cbc mode with hmac/sha1' => 'des3-cbc-sha1', 'des cbc mode with crc-32' => 'des-cbc-crc', 'des cbc mode with rsa-md5' => 'des-cbc-md5', + 'aes-128 cts mode with 96-bit sha-1 hmac' => 'aes128-cts-hmac-sha1-96', 'aes-256 cts mode with 96-bit sha-1 hmac' => 'aes256-cts-hmac-sha1-96', - 'arcfour with hmac/md5' => 'rc4-hmac'); + 'arcfour with hmac/md5' => 'rc4-hmac', + + 'des3-cbc-sha1' => 'des3-cbc-sha1', + 'des-cbc-crc' => 'des-cbc-crc', + 'des-cbc-md5' => 'des-cbc-md5', + 'aes128-cts-hmac-sha1-96' => 'aes128-cts-hmac-sha1-96', + 'aes256-cts-hmac-sha1-96' => 'aes256-cts-hmac-sha1-96', + 'rc4-hmac' => 'rc4-hmac'); # Some global defaults to use. my $user = 'admin@EXAMPLE.COM'; @@ -159,7 +172,7 @@ my $date = strftime ('%Y-%m-%d %H:%M:%S', localtime $trace[2]); # Basic keytab creation and manipulation tests. SKIP: { - skip 'no keytab configuration', 52 unless -f 't/data/test.keytab'; + skip 'no keytab configuration', 53 unless -f 't/data/test.keytab'; # Set up our configuration. $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab'; @@ -296,6 +309,7 @@ EOO @trace) }; ok (defined ($object), 'Creating good principal succeeds'); + is ($@, '', ' with no error'); ok (created ('wallet/one'), ' and the principal was created'); SKIP: { skip 'no kadmin program test for Heimdal', 2 diff --git a/perl/t/object/password.t b/perl/t/object/password.t index 4fe6b50..306d82b 100644 --- a/perl/t/object/password.t +++ b/perl/t/object/password.t @@ -120,5 +120,6 @@ like ($pwd, qr{^.{$Wallet::Config::PWD_LENGTH_MIN}$}, # Clean up. $admin->destroy; END { + system ('rm -r test-files') == 0 or die "cannot remove test-files\n"; unlink ('wallet-db'); } diff --git a/perl/t/verifier/external.t b/perl/t/verifier/external.t new file mode 100755 index 0000000..3e7e776 --- /dev/null +++ b/perl/t/verifier/external.t @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# +# Tests for the external wallet ACL verifier. +# +# Written by Russ Allbery <eagle@eyrie.org> +# Copyright 2016 Russ Allbery <eagle@eyrie.org> +# +# See LICENSE for licensing terms. + +use strict; +use warnings; + +use Test::More tests => 9; + +use Wallet::ACL::External; +use Wallet::Config; + +# Configure the external ACL verifier. +$Wallet::Config::EXTERNAL_COMMAND = 't/data/acl-command'; + +# Check a few verifications. +my $verifier = Wallet::ACL::External->new; +ok (defined $verifier, 'Wallet::ACL::External creation'); +ok ($verifier->isa ('Wallet::ACL::External'), ' and class verification'); +is ($verifier->check ('eagle@eyrie.org', 'test success'), 1, 'Success'); +is ($verifier->check ('eagle@eyrie.org', 'test failure'), 0, 'Failure'); +is ($verifier->error, undef, 'No error set'); +is ($verifier->check ('eagle@eyrie.org', 'test error'), undef, 'Error'); +is ($verifier->error, 'some error', ' and right error'); +is ($verifier->check (undef, 'eagle@eyrie.org'), undef, + 'Undefined principal'); +is ($verifier->error, 'no principal specified', ' and right error'); diff --git a/server/wallet-report b/server/wallet-report index 4719a8a..22637ca 100755 --- a/server/wallet-report +++ b/server/wallet-report @@ -135,7 +135,7 @@ wallet-report - Wallet server reporting interface =for stopwords metadata ACL hostname backend acl acls wildcard SQL Allbery remctl -MERCHANTABILITY NONINFRINGEMENT sublicense +MERCHANTABILITY NONINFRINGEMENT sublicense unstored =head1 SYNOPSIS @@ -207,6 +207,10 @@ Returns all ACLs containing an entry with given scheme and identifier. The scheme must be an exact match, but the <identifier> string will match any identifier containing that string. +=item acls nested <acl> + +Returns all ACLs that contain this ACL as a nested entry. + =item acls unused Returns all ACLs that are not referenced by any of the objects in the @@ -274,6 +278,12 @@ those where that ACL has any other, more limited permissions. Returns all objects which have the given flag set. +=item objects host <hostname> + +Returns all objects that belong to the given host. This requires adding +local configuration to identify objects that belong to a given host. See +L<Wallet::Config/"OBJECT HOST-BASED NAMES"> for more information. + =item objects owner <acl> Returns all objects owned by the given ACL name or ID. @@ -302,6 +312,14 @@ The output will be one line per ACL line in the form: with duplicates suppressed. +=item schemes + +Returns a list of all registered ACL schemes. + +=item types + +Returns a list of all registered object types. + =back =head1 AUTHOR @@ -310,7 +328,9 @@ Russ Allbery <eagle@eyrie.org> =head1 COPYRIGHT AND LICENSE -Copyright 2008, 2009, 2010, 2013 The Board of Trustees of the Leland +Copyright 2016 Russ Allbery <eagle@eyrie.org> + +Copyright 2008, 2009, 2010, 2013, 2015 The Board of Trustees of the Leland Stanford Junior University Permission is hereby granted, free of charge, to any person obtaining a |