# HG changeset patch # User Huie-Ying Lee # Date 1307583476 25200 # Node ID b454e61af367f63dd7ed10575473529071d5d853 # Parent 4a5d715e84b418f6a77cf9461dedd78837ca5abd 7050151 migrate pam_pkcs11 from sfw to userland diff -r 4a5d715e84b4 -r b454e61af367 components/meta-packages/history/SUNWpampkcs11.p5m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/meta-packages/history/SUNWpampkcs11.p5m Wed Jun 08 18:37:56 2011 -0700 @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# + +# +# Legacy package information for renamed SUNWpampkcs11 package +# + +set name=pkg.fmri value=pkg:/SUNWpampkcs11@0.6.0,5.11-0.133 +set name=pkg.renamed value=true + +set name=org.opensolaris.consolidation value=$(CONSOLIDATION) + +depend fmri=library/security/pam/module/pam-pkcs11@0.6.0-0.133 type=require diff -r 4a5d715e84b4 -r b454e61af367 components/pam_pkcs11/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/pam_pkcs11/Makefile Wed Jun 08 18:37:56 2011 -0700 @@ -0,0 +1,50 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# +include ../../make-rules/shared-macros.mk + +COMPONENT_NAME= pam_pkcs11 +COMPONENT_VERSION= 0.6.0 +COMPONENT_SRC= $(COMPONENT_NAME)-$(COMPONENT_VERSION) +COMPONENT_ARCHIVE= $(COMPONENT_SRC).tar.gz +COMPONENT_ARCHIVE_HASH= sha1:eef40325afc426e5364f0d9762a8e0aded34a6c2 +COMPONENT_ARCHIVE_URL= http://www.opensc-project.org/files/$(COMPONENT_NAME)/$(COMPONENT_ARCHIVE) + +include ../../make-rules/prep.mk +include ../../make-rules/configure.mk +include ../../make-rules/ips.mk + +CONFIGURE_OPTIONS += CFLAGS="$(CFLAGS)" +CONFIGURE_OPTIONS += --with-pcsclite=no +CONFIGURE_OPTIONS += --with-included-gettext=yes +CONFIGURE_OPTIONS += --localstatedir=/var + +# common targets +build: $(BUILD_32_and_64) + +install: $(INSTALL_32_and_64) + +test: $(NO_TESTS) + +BUILD_PKG_DEPENDENCIES = $(BUILD_TOOLS) + +include ../../make-rules/depend.mk diff -r 4a5d715e84b4 -r b454e61af367 components/pam_pkcs11/pam_pkcs11.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/pam_pkcs11/pam_pkcs11.conf Wed Jun 08 18:37:56 2011 -0700 @@ -0,0 +1,276 @@ +# +# Configuration file for pam_pkcs11 module +# +# Original Author: Juan Antonio Martinez +# +pam_pkcs11 { + # Allow empty passwords + nullok = true; + + # Enable debugging support. + debug = true; + + # Filename of the PKCS #11 module. The default value is "default" + use_pkcs11_module = default; + + pkcs11_module default { + module = /usr/lib/libpkcs11.so; + description = "Solaris PKCS#11 Cryptographic Framework library"; + + # Which slot to use? + # You can use "slot_description" or "slot_num", but not both, to specify + # the slot to use. Using "slot_description" is preferred because the + # PKCS#11 specification does not guarantee slot ordering. "slot_num" should + # only be used with those PKCS#11 implementations that guarantee + # constant slot numbering. + # + # slot_description = "xxxx" + # The slot is specified by the slot description, for example, + # slot_description = "Sun Crypto Softtoken". The default value is + # "none" which means to use the first slot with an available token. + # + # slot_num = a_number + # The slot is specified by the slot number, for example, slot_num = 1. + # The default value is zero which means to use the first slot with an + # available token. + # + # On Solaris OS, an administrator can use the "cryotoadm list -v" command + # to find all the available slots and their slot descriptions. For more + # information, see the libpkcs11(3LIB) and cryptoadm(1m) man pages. + # + slot_description = "none"; + + # Where are CA certificates stored? + # You can setup this value to: + # 1- A directory with openssl hash-links to all certificates + # 2- A CA file in PEM (.pem) or ASN1 (.cer) format, + # containing all allowed CA certs + # The default value is /etc/security/pam_pkcs11/cacerts. + ca_dir = /etc/security/pam_pkcs11/cacerts; + + # Path to the directory where the local (offline) CRLs are stored. + # Same convention as above is applied: you can choose either + # hash-link directory or CRL file + # The default value is /etc/security/pam_pkcs11/crls. + crl_dir = /etc/security/pam_pkcs11/crls; + + # Some pcks#11 libraries can handle multithreading. So + # set it to true to properly call C_Initialize() + support_threads = false; + + # Sets the Certificate verification policy. + # "none" Performs no verification + # "ca" Does CA check + # "crl_online" Downloads the CRL form the location given by the + # CRL distribution point extension of the certificate + # "crl_offline" Uses the locally stored CRLs + # "crl_auto" Is a combination of online and offline; it first + # tries to download the CRL from a possibly given CRL + # distribution point and if this fails, uses the local + # CRLs + # "signature" Does also a signature check to ensure that private + # and public key matches + # You can use a combination of ca,crl, and signature flags, or just + # use "none". + # cert_policy = ca,signature; + cert_policy = signature; + + # What kind of token? + # The value of the token_type parameter will be used in the user prompt + # messages. The default value is "Smart card". + token_type = "Secure token"; + } + + # Which mappers ( Cert to login ) to use? + # you can use several mappers: + # + # subject - Cert Subject to login file based mapper + # pwent - CN to getpwent() login or gecos fields mapper + # ldap - LDAP mapper + # opensc - Search certificate in ${HOME}/.eid/authorized_certificates + # openssh - Search certificate public key in ${HOME}/.ssh/authorized_keys + # mail - Compare email fields from certificate + # ms - Use Microsoft Universal Principal Name extension + # krb - Compare againts Kerberos Principal Name + # cn - Compare Common Name (CN) + # uid - Compare Unique Identifier + # digest - Certificate digest to login (mapfile based) mapper + # generic - User defined certificate contents mapped + # null - blind access/deny mapper + # + # You can select a comma-separated mapper list. + # If used null mapper should be the last in the list :-) + # Also you should select at least one mapper, otherwise + # certificate will not match :-) + # use_mappers = digest, cn, pwent, uid, mail, subject, null; + use_mappers = cn; + + # When no absolute path or module info is provided, use this + # value as module search path + # TODO: + # This is not still functional: use absolute pathnames or LD_LIBRARY_PATH + mapper_search_path = /usr/lib/pam_pkcs11; + + # + # Generic certificate contents mapper + mapper generic { + debug = true; + module = internal; + # ignore letter case on match/compare + ignorecase = false; + # Use one of "cn" , "subject" , "kpn" , "email" , "upn" or "uid" + cert_item = cn; + # Define mapfile if needed, else select "none" + mapfile = file:///etc/security/pam_pkcs11/generic_mapping + # Decide if use getpwent() to map login + use_getpwent = false; + } + + # Certificate Subject to login based mapper + # provided file stores one or more "Subject -> login" lines + mapper subject { + debug = false; + module = internal; + ignorecase = false; + mapfile = file:///etc/security/pam_pkcs11/subject_mapping; + } + + # Search public keys from $HOME/.ssh/authorized_keys to match users + mapper openssh { + debug = false; + module = /usr/lib/pam_pkcs11/openssh_mapper.so; + } + + # Search certificates from $HOME/.eid/authorized_certificates to match users + mapper opensc { + debug = false; + module = /usr/lib/pam_pkcs11/opensc_mapper.so; + } + + # Certificate Common Name ( CN ) to getpwent() mapper + mapper pwent { + debug = false; + ignorecase = false; + module = internal; + } + + # Null ( no map ) mapper. when user as finder matchs to NULL or "nobody" + mapper null { + debug = false; + module = internal ; + # select behavior: always match, or always fail + default_match = false; + # on match, select returned user + default_user = nobody ; + } + + # Directory ( ldap style ) mapper + mapper ldap { + debug = false; + module = /usr/lib/pam_pkcs11/ldap_mapper.so; + # hostname of ldap server (use LDAP-URI for more then one) + ldaphost = ""; + # Port on ldap server to connect, this is also the default + # if no port is given in URI below + # if empty, then 389 for TLS and 636 for SSL is used + ldapport = ; + # space separted list of LDAP URIs (URIs are used by given order) + URI = ""; + # Scope of search: 0-2 + # Default is 1 = "one", meaning the set of records one + # level below the basedn. + # 0 = "base" means search only the basedn, and + # 2 = "sub" means the union of entries at the "base" level + # and ? all or "one" level below ??? FIXME + scope = 2; + # DN to bind with. Must have read-access for user entries + # under "base" + binddn = "cn=pam,o=example,c=com"; + # Password for above DN + passwd = ""; + # Searchbase for user entries + base = "ou=People,o=example,c=com"; + # Attribute of user entry which contains the certificate + attribute = "userCertificate"; + # Searchfilter for user entry. Must only let pass user entry + # for the login user. + filter = "(&(objectClass=posixAccount)(uid=%s))" + # SSL/TLS-Switch + # This is a global switch, you can't switch between + # SSL or TLS and non secured connections per URI! + # values: off (standard), tls or on (ssl) or ssl + ssl = tls + # SSL specific settings + # tls_randfile = ... + tls_cacertfile = /etc/ssl/cacert.pem + # tls_cacertdir = ... + tls_checkpeer = 0 + #tls_ciphers = ... + #tls_cert = ... + #tls_key = ... + } + + # Assume common name (CN) to be the login + mapper cn { + debug = false; + module = internal; + ignorecase = true; + # mapfile = file:///etc/security/pam_pkcs11/cn_map; + mapfile = "none"; + } + + # mail - Compare email field from certificate + mapper mail { + debug = false; + module = internal; + # Declare mapfile or + # leave empty "" or "none" to use no map + mapfile = file:///etc/security/pam_pkcs11/mail_mapping; + # Some certs store email in uppercase. take care on this + ignorecase = true; + # Also check that host matches mx domain + # when using mapfile this feature is ignored + ignoredomain = false; + } + + # ms - Use Microsoft Universal Principal Name extension + # UPN is in format login@ADS_Domain. No map is needed, just + # check domain name. + mapper ms { + debug = false; + module = internal; + ignorecase = false; + ignoredomain = false; + domain = "domain.com"; + } + + # krb - Compare againts Kerberos Principal Name + mapper krb { + debug = false; + module = internal; + ignorecase = false; + mapfile = "none"; + } + + # uid - Maps Subject Unique Identifier field (if exist) to login + mapper uid { + debug = false; + module = internal; + ignorecase = false; + mapfile = "none"; + } + + # digest - elaborate certificate digest and map it into a file + mapper digest { + debug = false; + module = internal; + # algorithm used to evaluate certificate digest + # Select one of: + # "null","md2","md4","md5","sha","sha1","dss","dss1","ripemd160" + algorithm = "sha1"; + # mapfile = file:///etc/security/pam_pkcs11/digest_mapping; + mapfile = "none"; + + } + +} diff -r 4a5d715e84b4 -r b454e61af367 components/pam_pkcs11/pam_pkcs11.license --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/pam_pkcs11/pam_pkcs11.license Wed Jun 08 18:37:56 2011 -0700 @@ -0,0 +1,512 @@ +Oracle elects to use only the GNU Lesser General Public License version +2.1 (LGPL)/GNU General Public License version 2 (GPL) for any software +where a choice of LGPL/GPL license versions are made available with the +language indicating that LGPLv2.1/GPLv2 or any later version may be +used, or where a choice of which version of the LGPL/GPL is applied is +unspecified. Unless specifically stated otherwise, where a choice +exists between another license and either the GPL or the LGPL, Oracle +chooses the other license. +----------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff -r 4a5d715e84b4 -r b454e61af367 components/pam_pkcs11/pam_pkcs11.p5m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/pam_pkcs11/pam_pkcs11.p5m Wed Jun 08 18:37:56 2011 -0700 @@ -0,0 +1,89 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# + +set name=pkg.fmri \ + value=pkg:/library/security/pam/module/pam-pkcs11@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION) +set name=pkg.summary value="The OpenSC PKCS#11 PAM Login Tools" +set name=info.classification \ + value="org.opensolaris.category.2008:System/Security" +set name=info.source_url value=$(COMPONENT_ARCHIVE_URL) +set name=info.upstream_url value=http://www.opensc-project.org +set name=opensolaris.arc_url \ + value=http://arc.opensolaris.org/caselog/PSARC/2006/283 +set name=org.opensolaris.consolidation value=$(CONSOLIDATION) + +dir path=etc +dir path=etc/security +dir path=etc/security/pam_pkcs11 +dir path=etc/security/pam_pkcs11/cacerts +dir path=etc/security/pam_pkcs11/crls +dir path=usr +dir path=usr/lib +dir path=usr/lib/pam_pkcs11 +dir path=usr/lib/pam_pkcs11/$(MACH64) +dir path=usr/lib/security +dir path=usr/lib/security/$(MACH64) +dir path=usr/share +dir path=usr/share/doc +dir path=usr/share/doc/pam_pkcs11 +dir path=usr/share/locale +dir path=usr/share/locale/fr +dir path=usr/share/locale/fr/LC_MESSAGES + +file pam_pkcs11.conf path=etc/security/pam_pkcs11/pam_pkcs11.conf mode=0644 \ + preserve=renamenew \ + original_name=SUNWpampkcs11:etc/security/pam_pkcs11/pam_pkcs11.conf +file usr/bin/make_hash_link.sh \ + path=etc/security/pam_pkcs11/make_hash_link.sh mode=0555 +file usr/share/pam_pkcs11/digest_mapping.example \ + path=etc/security/pam_pkcs11/digest_mapping.example +file usr/share/pam_pkcs11/mail_mapping.example \ + path=etc/security/pam_pkcs11/mail_mapping.example +file usr/share/pam_pkcs11/subject_mapping.example \ + path=etc/security/pam_pkcs11/subject_mapping.example +file usr/bin/pkcs11_inspect path=usr/lib/pam_pkcs11/pkcs11_inspect mode=0555 +file usr/bin/pklogin_finder path=usr/lib/pam_pkcs11/pklogin_finder mode=0555 +file usr/lib/security/pam_pkcs11.so path=usr/lib/security/pam_pkcs11.so +file usr/lib/$(MACH64)/security/pam_pkcs11.so \ + path=usr/lib/security/$(MACH64)/pam_pkcs11.so +file path=usr/lib/pam_pkcs11/ldap_mapper.so +file path=usr/lib/pam_pkcs11/opensc_mapper.so +file path=usr/lib/pam_pkcs11/openssh_mapper.so +file usr/lib/$(MACH64)/pam_pkcs11/ldap_mapper.so \ + path=usr/lib/pam_pkcs11/$(MACH64)/ldap_mapper.so +file usr/lib/$(MACH64)/pam_pkcs11/opensc_mapper.so \ + path=usr/lib/pam_pkcs11/$(MACH64)/opensc_mapper.so +file usr/lib/$(MACH64)/pam_pkcs11/openssh_mapper.so \ + path=usr/lib/pam_pkcs11/$(MACH64)/openssh_mapper.so +file path=usr/share/locale/fr/LC_MESSAGES/pam_pkcs11.mo +file doc/pam_pkcs11.html path=usr/share/doc/pam_pkcs11/pam_pkcs11.html +file doc/mappers_api.html path=usr/share/doc/pam_pkcs11/mappers_api.html + +legacy pkg=SUNWpampkcs11u desc="The OpenSC PKCS#11 PAM Login Tools 0.6.0" \ + name="The OpenSC PKCS#11 PAM Login Tools" +legacy pkg=SUNWpampkcs11r desc="The OpenSC PKCS#11 PAM Login Tools 0.6.0" \ + name="The OpenSC PKCS#11 PAM Login Tools" +legacy pkg=SUNWpampkcs11-docs desc="The OpenSC PKCS#11 PAM Login Tools 0.6.0" \ + name="The OpenSC PKCS#11 PAM Login Tools" + +license pam_pkcs11.license license=LGPLv2.1 diff -r 4a5d715e84b4 -r b454e61af367 components/pam_pkcs11/patches/pam_pkcs11.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/pam_pkcs11/patches/pam_pkcs11.patch Wed Jun 08 18:37:56 2011 -0700 @@ -0,0 +1,1574 @@ +*** pam_pkcs11-0.6.0-ORIG/configure.in Mon Jun 11 05:17:38 2007 +--- pam_pkcs11-WS/configure.in Mon Sep 28 16:06:48 2009 +*************** +*** 237,243 **** + AC_FUNC_REALLOC + AC_FUNC_STAT + AC_FUNC_VPRINTF +! AC_CHECK_FUNCS([memset strdup strerror]) + + + AC_CONFIG_FILES([ +--- 237,243 ---- + AC_FUNC_REALLOC + AC_FUNC_STAT + AC_FUNC_VPRINTF +! AC_CHECK_FUNCS([memset strdup strerror daemon]) + + + AC_CONFIG_FILES([ +*** pam_pkcs11-0.6.0-ORIG/po/Makefile.in.in Tue May 22 00:54:56 2007 +--- pam_pkcs11-WS/po/Makefile.in.in Mon Sep 28 16:06:48 2009 +*************** +*** 46,61 **** + GMSGFMT_ = @GMSGFMT@ + GMSGFMT_no = @GMSGFMT@ + GMSGFMT_yes = @GMSGFMT_015@ +! GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) + MSGFMT_ = @MSGFMT@ + MSGFMT_no = @MSGFMT@ + MSGFMT_yes = @MSGFMT_015@ + MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +! XGETTEXT_ = @XGETTEXT@ + XGETTEXT_no = @XGETTEXT@ + XGETTEXT_yes = @XGETTEXT_015@ + XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +! MSGMERGE = msgmerge + MSGMERGE_UPDATE = @MSGMERGE@ --update + MSGINIT = msginit + MSGCONV = msgconv +--- 46,61 ---- + GMSGFMT_ = @GMSGFMT@ + GMSGFMT_no = @GMSGFMT@ + GMSGFMT_yes = @GMSGFMT_015@ +! GMSGFMT = msgfmt + MSGFMT_ = @MSGFMT@ + MSGFMT_no = @MSGFMT@ + MSGFMT_yes = @MSGFMT_015@ + MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +! XGETTEXT_ = /bin/xgettext + XGETTEXT_no = @XGETTEXT@ + XGETTEXT_yes = @XGETTEXT_015@ + XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +! MSGMERGE = /usr/lib/intltool/gettext-tools/msgmerge + MSGMERGE_UPDATE = @MSGMERGE@ --update + MSGINIT = msginit + MSGCONV = msgconv +*************** +*** 87,94 **** + .po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ +! echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ +! cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + + .sin.sed: + sed -e '/^#/d' $< > t-$@ +--- 87,94 ---- + .po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ +! echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -o $${lang}.gmo $${lang}.po"; \ +! cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + + .sin.sed: + sed -e '/^#/d' $< > t-$@ +*************** +*** 135,145 **** + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ +! $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ +! --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ +! --files-from=$(srcdir)/POTFILES.in \ +! --copyright-holder='$(COPYRIGHT_HOLDER)' \ +! --msgid-bugs-address="$$msgid_bugs_address" + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ +--- 135,142 ---- + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ +! $(XGETTEXT) -ns -c TRANSLATORS: -m "" -d $(DOMAIN) \ +! ../src/pam_pkcs11/pam_pkcs11.c + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ +*** pam_pkcs11-0.6.0-ORIG/src/common/pkcs11_lib.h Mon May 21 02:46:19 2007 +--- pam_pkcs11-WS/src/common/pkcs11_lib.h Mon Sep 28 16:06:48 2009 +*************** +*** 36,46 **** + PKCS11_EXTERN int find_slot_by_number_and_label(pkcs11_handle_t *h, + int slot_num, const char *slot_label, + unsigned int *slot); +! PKCS11_EXTERN const char *get_slot_label(pkcs11_handle_t *h); + PKCS11_EXTERN int wait_for_token(pkcs11_handle_t *h, + int wanted_slot_num, + const char *wanted_slot_label, + unsigned int *slot); + PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert); + PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h); + PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot); +--- 36,57 ---- + PKCS11_EXTERN int find_slot_by_number_and_label(pkcs11_handle_t *h, + int slot_num, const char *slot_label, + unsigned int *slot); +! PKCS11_EXTERN const char *get_slot_tokenlabel(pkcs11_handle_t *h); + PKCS11_EXTERN int wait_for_token(pkcs11_handle_t *h, + int wanted_slot_num, ++ const char *wanted_token_label, ++ unsigned int *slot); ++ PKCS11_EXTERN int find_slot_by_slotlabel(pkcs11_handle_t *h, + const char *wanted_slot_label, + unsigned int *slot); ++ PKCS11_EXTERN int find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h, ++ const char *wanted_slot_label, ++ const char *wanted_token_label, ++ unsigned int *slot); ++ PKCS11_EXTERN int wait_for_token_by_slotlabel(pkcs11_handle_t *h, ++ const char *wanted_slot_label, ++ const char *wanted_token_label, ++ unsigned int *slot); + PKCS11_EXTERN const X509 *get_X509_certificate(cert_object_t *cert); + PKCS11_EXTERN void release_pkcs11_module(pkcs11_handle_t *h); + PKCS11_EXTERN int open_pkcs11_session(pkcs11_handle_t *h, unsigned int slot); +*** pam_pkcs11-0.6.0-ORIG/src/common/pkcs11_lib.c Wed Jun 6 02:33:10 2007 +--- pam_pkcs11-WS/src/common/pkcs11_lib.c Mon Sep 28 16:06:48 2009 +*************** +*** 67,77 **** +--- 67,138 ---- + return 0; + } + ++ /* ++ * memcmp_pad_max() is a specialized version of memcmp() which compares two ++ * pieces of data up to a maximum length. If the two data match up the ++ * maximum length, they are considered matching. Trailing blanks do not cause ++ * the match to fail if one of the data is shorted. ++ * ++ * Examples of matches: ++ * "one" | ++ * "one " | ++ * ^maximum length ++ * ++ * "Number One | X" (X is beyond maximum length) ++ * "Number One " | ++ * ^maximum length ++ * ++ * Examples of mismatches: ++ * " one" ++ * "one" ++ * ++ * "Number One X|" ++ * "Number One |" ++ * ^maximum length ++ */ ++ static int ++ memcmp_pad_max(void *d1, size_t d1_len, void *d2, size_t d2_len, ++ size_t max_sz) ++ { ++ size_t len, extra_len; ++ char *marker; ++ ++ /* No point in comparing anything beyond max_sz */ ++ if (d1_len > max_sz) ++ d1_len = max_sz; ++ if (d2_len > max_sz) ++ d2_len = max_sz; ++ ++ /* Find shorter of the two data. */ ++ if (d1_len <= d2_len) { ++ len = d1_len; ++ extra_len = d2_len; ++ marker = d2; ++ } else { /* d1_len > d2_len */ ++ len = d2_len; ++ extra_len = d1_len; ++ marker = d1; ++ } ++ ++ /* Have a match in the shortest length of data? */ ++ if (memcmp(d1, d2, len) != 0) ++ /* CONSTCOND */ ++ return (1); ++ ++ /* If the rest of longer data is nulls or blanks, call it a match. */ ++ while (len < extra_len && marker[len]) ++ if (!isspace(marker[len++])) ++ /* CONSTCOND */ ++ return (1); ++ return (0); ++ } ++ + #ifdef HAVE_NSS + /* + * Using NSS to find the manage the PKCS #11 modules + */ + #include "nss.h" ++ #include "nspr.h" + #include "cert.h" + #include "secmod.h" + #include "pk11pub.h" +*************** +*** 287,294 **** + /* we're configured for a specific module and token, see if it's present */ + slot_num--; + if (slot_num >= 0 && slot_num < module->slotCount && module->slots && +! module->slots[i] && PK11_IsPresent(module->slots[i])) { +! h->slot = PK11_ReferenceSlot(module->slots[i]); + *slotID = PK11_GetSlotID(h->slot); + return 0; + } +--- 348,355 ---- + /* we're configured for a specific module and token, see if it's present */ + slot_num--; + if (slot_num >= 0 && slot_num < module->slotCount && module->slots && +! module->slots[slot_num] && PK11_IsPresent(module->slots[slot_num])) { +! h->slot = PK11_ReferenceSlot(module->slots[slot_num]); + *slotID = PK11_GetSlotID(h->slot); + return 0; + } +*************** +*** 301,327 **** + */ + int find_slot_by_number_and_label(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_slot_label, + unsigned int *slot_num) + { + int rv; +! const char *slot_label = NULL; + PK11SlotInfo *slot = NULL; + + /* we want a specific slot id, or we don't kare about the label */ +! if ((wanted_slot_label == NULL) || (wanted_slot_id != 0)) { + rv = find_slot_by_number(h, wanted_slot_id, slot_num); + + /* if we don't care about the label, or we failed, we're done */ +! if ((wanted_slot_label == NULL) || (rv != 0)) { + return rv; + } + + /* verify it's the label we want */ +! slot_label = PK11_GetTokenName(h->slot); + +! if ((slot_label != NULL) && +! (strcmp (wanted_slot_label, slot_label) == 0)) { + return 0; + } + return -1; +--- 362,388 ---- + */ + int find_slot_by_number_and_label(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_token_label, + unsigned int *slot_num) + { + int rv; +! const char *token_label = NULL; + PK11SlotInfo *slot = NULL; + + /* we want a specific slot id, or we don't kare about the label */ +! if ((wanted_token_label == NULL) || (wanted_slot_id != 0)) { + rv = find_slot_by_number(h, wanted_slot_id, slot_num); + + /* if we don't care about the label, or we failed, we're done */ +! if ((wanted_token_label == NULL) || (rv != 0)) { + return rv; + } + + /* verify it's the label we want */ +! token_label = PK11_GetTokenName(h->slot); + +! if ((token_label != NULL) && +! (strcmp (wanted_token_label, token_label) == 0)) { + return 0; + } + return -1; +*************** +*** 328,334 **** + } + + /* we want a specific slot by label only */ +! slot = PK11_FindSlotByName(wanted_slot_label); + if (!slot) { + return -1; + } +--- 389,395 ---- + } + + /* we want a specific slot by label only */ +! slot = PK11_FindSlotByName(wanted_token_label); + if (!slot) { + return -1; + } +*************** +*** 350,356 **** + + int wait_for_token(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_slot_label, + unsigned int *slot_num) + { + int rv; +--- 411,417 ---- + + int wait_for_token(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_token_label, + unsigned int *slot_num) + { + int rv; +*************** +*** 358,364 **** + rv = -1; + do { + /* see if the card we're looking for is inserted */ +! rv = find_slot_by_number_and_label (h, wanted_slot_id, wanted_slot_label, + slot_num); + if (rv != 0) { + PK11SlotInfo *slot; +--- 419,425 ---- + rv = -1; + do { + /* see if the card we're looking for is inserted */ +! rv = find_slot_by_number_and_label (h, wanted_slot_id, wanted_token_label, + slot_num); + if (rv != 0) { + PK11SlotInfo *slot; +*************** +*** 385,390 **** +--- 446,592 ---- + return rv; + } + ++ /* ++ * This function will search the slot list to find a slot based on the slot ++ * label. If the wanted_slot_label is "none", then we will return the first ++ * slot with the token presented. ++ * ++ * This function return 0 if it found a matching slot; otherwise, it returns ++ * -1. ++ */ ++ int ++ find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label, ++ unsigned int *slotID) ++ { ++ SECMODModule *module = h->module; ++ PK11SlotInfo *slot; ++ int rv; ++ int i; ++ ++ if (slotID == NULL || wanted_slot_label == NULL || ++ strlen(wanted_slot_label) == 0 || module == NULL) ++ return (-1); ++ ++ if (strcmp(wanted_slot_label, "none") == 0) { ++ rv = find_slot_by_number(h, 0, slotID); ++ return (rv); ++ } else { ++ /* wanted_slot_label is not "none" */ ++ for (i = 0; i < module->slotCount; i++) { ++ if (module->slots[i] && PK11_IsPresent(module->slots[i])) { ++ const char *slot_label; ++ ++ slot = PK11_ReferenceSlot(module->slots[i]); ++ slot_label = PK11_GetSlotName(slot); ++ if (memcmp_pad_max((void *)slot_label, strlen(slot_label), ++ (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) { ++ h->slot = slot; ++ *slotID = PK11_GetSlotID(slot); ++ return 0; ++ } ++ } ++ } ++ } ++ ++ return (-1); ++ } ++ ++ int ++ find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h, ++ const char *wanted_slot_label, const char *wanted_token_label, ++ unsigned int *slot_num) ++ { ++ SECMODModule *module = h->module; ++ PK11SlotInfo *slot; ++ unsigned long i; ++ int rv; ++ ++ if (slot_num == NULL || module == NULL) ++ return (-1); ++ ++ if (wanted_token_label == NULL){ ++ rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num); ++ return (rv); ++ } ++ ++ /* wanted_token_label != NULL */ ++ if (strcmp(wanted_slot_label, "none") == 0) { ++ for (i = 0; i < module->slotCount; i++) { ++ if (module->slots[i] && PK11_IsPresent(module->slots[i])) { ++ const char *token_label; ++ slot = PK11_ReferenceSlot(module->slots[i]); ++ token_label = PK11_GetTokenName(slot); ++ if (memcmp_pad_max((void *) token_label, strlen(token_label), ++ (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0) { ++ h->slot = slot; ++ *slot_num = PK11_GetSlotID(slot); ++ return (0); ++ } ++ } ++ } ++ return (-1); ++ } else { ++ for (i = 0; i < module->slotCount; i++) { ++ if (module->slots[i] && PK11_IsPresent(module->slots[i])) { ++ const char *slot_label; ++ const char *token_label; ++ ++ slot = PK11_ReferenceSlot(module->slots[i]); ++ slot_label = PK11_GetSlotName(slot); ++ token_label = PK11_GetTokenName(slot); ++ if ((memcmp_pad_max((void *)slot_label, strlen(slot_label), ++ (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) && ++ (memcmp_pad_max((void *)token_label, strlen(token_label), ++ (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0)) ++ { ++ h->slot = slot; ++ *slot_num = PK11_GetSlotID(slot); ++ return (0); ++ } ++ } ++ } ++ return (-1); ++ } ++ } ++ ++ int wait_for_token_by_slotlabel(pkcs11_handle_t *h, ++ const char *wanted_slot_label, ++ const char *wanted_token_label, ++ unsigned int *slot_num) ++ { ++ int rv; ++ ++ rv = -1; ++ do { ++ /* see if the card we're looking for is inserted */ ++ rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label, ++ wanted_token_label, slot_num); ++ ++ if (rv != 0) { ++ PK11SlotInfo *slot; ++ PRIntervalTime slot_poll_interval; /* only for legacy hardware */ ++ ++ /* if the card is not inserted, then block until something happens */ ++ slot_poll_interval = PR_MillisecondsToInterval(PAM_PKCS11_POLL_TIME); ++ slot = SECMOD_WaitForAnyTokenEvent(h->module, 0 /* flags */, ++ slot_poll_interval); ++ ++ /* unexpected error */ ++ if (slot == NULL) { ++ break; ++ } ++ ++ /* something happened, continue loop and check if the card ++ * we're looking for is inserted ++ */ ++ PK11_FreeSlot(slot); ++ continue; ++ } ++ } while (rv != 0); ++ ++ return rv; ++ } ++ + void release_pkcs11_module(pkcs11_handle_t *h) + { + SECStatus rv; +*************** +*** 470,476 **** + return 0; + } + +! const char *get_slot_label(pkcs11_handle_t *h) + { + if (!h->slot) { + return NULL; +--- 672,678 ---- + return 0; + } + +! const char *get_slot_tokenlabel(pkcs11_handle_t *h) + { + if (!h->slot) { + return NULL; +*************** +*** 613,619 **** + return (rv == SECSuccess) ? 0 : -1; + } + +- #include "nspr.h" + + struct tuple_str { + PRErrorCode errNum; +--- 815,820 ---- +*************** +*** 708,714 **** + typedef struct { + CK_SLOT_ID id; + CK_BBOOL token_present; +! CK_UTF8CHAR label[33]; + } slot_t; + + struct pkcs11_handle_str { +--- 909,916 ---- + typedef struct { + CK_SLOT_ID id; + CK_BBOOL token_present; +! CK_UTF8CHAR label[33]; /* token label */ +! CK_UTF8CHAR slotDescription[64]; + } slot_t; + + struct pkcs11_handle_str { +*************** +*** 758,764 **** + DBG3("module permissions: uid = %d, gid = %d, mode = %o", + module_stat.st_uid, module_stat.st_gid, module_stat.st_mode & 0777); + if (module_stat.st_mode & S_IWGRP || module_stat.st_mode & S_IWOTH +! || module_stat.st_uid != 0 || module_stat.st_gid != 0) { + set_error("the pkcs #11 module MUST be owned by root and MUST NOT " + "be writeable by the group or others"); + free(h); +--- 960,966 ---- + DBG3("module permissions: uid = %d, gid = %d, mode = %o", + module_stat.st_uid, module_stat.st_gid, module_stat.st_mode & 0777); + if (module_stat.st_mode & S_IWGRP || module_stat.st_mode & S_IWOTH +! || module_stat.st_uid != 0) { + set_error("the pkcs #11 module MUST be owned by root and MUST NOT " + "be writeable by the group or others"); + free(h); +*************** +*** 807,812 **** +--- 1009,1018 ---- + set_error("C_GetSlotInfo() failed: %x", rv); + return -1; + } ++ ++ (void) memcpy(h->slots[i].slotDescription, sinfo.slotDescription, ++ sizeof(h->slots[i].slotDescription)); ++ + DBG1("- description: %.64s", sinfo.slotDescription); + DBG1("- manufacturer: %.32s", sinfo.manufacturerID); + DBG1("- flags: %04lx", sinfo.flags); +*************** +*** 945,971 **** + + int find_slot_by_number_and_label(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_slot_label, + unsigned int *slot_num) + { + unsigned int slot_index; + int rv; +! const char *slot_label = NULL; + + /* we want a specific slot id, or we don't care about the label */ +! if ((wanted_slot_label == NULL) || (wanted_slot_id != 0)) { + rv = find_slot_by_number(h, wanted_slot_id, slot_num); + + /* if we don't care about the label, or we failed, we're done */ +! if ((wanted_slot_label == NULL) || (rv != 0)) { + return rv; + } + + /* verify it's the label we want */ +! slot_label = h->slots[*slot_num].label; + +! if ((slot_label != NULL) && +! (strcmp (wanted_slot_label, slot_label) == 0)) { + return 0; + } + return -1; +--- 1151,1177 ---- + + int find_slot_by_number_and_label(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_token_label, + unsigned int *slot_num) + { + unsigned int slot_index; + int rv; +! const char *token_label = NULL; + + /* we want a specific slot id, or we don't care about the label */ +! if ((wanted_token_label == NULL) || (wanted_slot_id != 0)) { + rv = find_slot_by_number(h, wanted_slot_id, slot_num); + + /* if we don't care about the label, or we failed, we're done */ +! if ((wanted_token_label == NULL) || (rv != 0)) { + return rv; + } + + /* verify it's the label we want */ +! token_label = h->slots[*slot_num].label; + +! if ((token_label != NULL) && +! (strcmp (wanted_token_label, token_label) == 0)) { + return 0; + } + return -1; +*************** +*** 974,982 **** + /* look up the slot by it's label from the list */ + for (slot_index = 0; slot_index < h->slot_count; slot_index++) { + if (h->slots[slot_index].token_present) { +! slot_label = h->slots[slot_index].label; +! if ((slot_label != NULL) && +! (strcmp (wanted_slot_label, slot_label) == 0)) { + *slot_num = slot_index; + return 0; + } +--- 1180,1188 ---- + /* look up the slot by it's label from the list */ + for (slot_index = 0; slot_index < h->slot_count; slot_index++) { + if (h->slots[slot_index].token_present) { +! token_label = h->slots[slot_index].label; +! if ((token_label != NULL) && +! (strcmp (wanted_token_label, token_label) == 0)) { + *slot_num = slot_index; + return 0; + } +*************** +*** 985,993 **** + return -1; + } + + int wait_for_token(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_slot_label, + unsigned int *slot_num) + { + int rv; +--- 1191,1310 ---- + return -1; + } + ++ /* ++ * This function will search the slot list to find a slot based on the slot ++ * label. If the wanted_slot_label is "none", then we will return the first ++ * slot with the token presented. ++ * ++ * This function return 0 if it found a matching slot; otherwise, it returns ++ * -1. ++ */ ++ int ++ find_slot_by_slotlabel(pkcs11_handle_t *h, const char *wanted_slot_label, ++ unsigned int *slot_num) ++ { ++ unsigned long index; ++ size_t len; ++ ++ if (slot_num == NULL || wanted_slot_label == NULL || ++ strlen(wanted_slot_label) == 0) ++ return (-1); ++ ++ if (strcmp(wanted_slot_label, "none") == 0) { ++ for (index = 0; index < h->slot_count; index++) { ++ if (h->slots[index].token_present) { ++ *slot_num = index; ++ return (0); ++ } ++ } ++ } else { ++ /* Look up the slot by it's slotDescription */ ++ len = strlen(wanted_slot_label); ++ for (index = 0; index < h->slot_count; index++) { ++ if (memcmp_pad_max(h->slots[index].slotDescription, 64, ++ (void *)wanted_slot_label, len, 64) == 0) { ++ *slot_num = index; ++ return (0); ++ } ++ } ++ } ++ ++ return (-1); ++ } ++ ++ ++ int ++ find_slot_by_slotlabel_and_tokenlabel(pkcs11_handle_t *h, ++ const char *wanted_slot_label, const char *wanted_token_label, ++ unsigned int *slot_num) ++ { ++ unsigned long i; ++ int rv; ++ ++ if (slot_num == NULL) ++ return (-1); ++ ++ if (wanted_token_label == NULL) { ++ rv = find_slot_by_slotlabel(h, wanted_slot_label, slot_num); ++ return (rv); ++ } ++ ++ /* wanted_token_label != NULL */ ++ if (strcmp(wanted_slot_label, "none") == 0) { ++ for (i= 0; i < h->slot_count; i++) { ++ if (h->slots[i].token_present && ++ strcmp(wanted_token_label, h->slots[i].label) == 0) { ++ *slot_num = i; ++ return (0); ++ } ++ } ++ return (-1); ++ } else { ++ for (i = 0; i < h->slot_count; i++) { ++ if (h->slots[i].token_present) { ++ const char *slot_label = h->slots[i].slotDescription; ++ const char *token_label = h->slots[i].label; ++ ++ if ((memcmp_pad_max((void *)slot_label, strlen(slot_label), ++ (void *)wanted_slot_label, strlen(wanted_slot_label), 64) == 0) && ++ (memcmp_pad_max((void *)token_label, strlen(token_label), ++ (void *)wanted_token_label, strlen(wanted_token_label), 33) == 0)) ++ { ++ *slot_num = i; ++ return (0); ++ } ++ } ++ } ++ return (-1); ++ } ++ } ++ ++ int wait_for_token_by_slotlabel(pkcs11_handle_t *h, ++ const char *wanted_slot_label, ++ const char *wanted_token_label, ++ unsigned int *slot_num) ++ { ++ int rv; ++ ++ rv = -1; ++ do { ++ /* see if the card we're looking for is inserted */ ++ rv = find_slot_by_slotlabel_and_tokenlabel (h, wanted_slot_label, ++ wanted_token_label, slot_num); ++ if (rv != 0) { ++ /* could call C_WaitForSlotEvent, for now just poll */ ++ sleep(10); ++ refresh_slots(h); ++ continue; ++ } ++ } while (rv != 0); ++ ++ return rv; ++ } ++ + int wait_for_token(pkcs11_handle_t *h, + int wanted_slot_id, +! const char *wanted_token_label, + unsigned int *slot_num) + { + int rv; +*************** +*** 995,1001 **** + rv = -1; + do { + /* see if the card we're looking for is inserted */ +! rv = find_slot_by_number_and_label (h, wanted_slot_id, wanted_slot_label, + slot_num); + if (rv != 0) { + /* could call C_WaitForSlotEvent, for now just poll */ +--- 1312,1318 ---- + rv = -1; + do { + /* see if the card we're looking for is inserted */ +! rv = find_slot_by_number_and_label (h, wanted_slot_id, wanted_token_label, + slot_num); + if (rv != 0) { + /* could call C_WaitForSlotEvent, for now just poll */ +*************** +*** 1306,1312 **** + return -1; + } + +! const char *get_slot_label(pkcs11_handle_t *h) + { + return h->slots[h->current_slot].label; + } +--- 1623,1629 ---- + return -1; + } + +! const char *get_slot_tokenlabel(pkcs11_handle_t *h) + { + return h->slots[h->current_slot].label; + } +*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/Makefile.in Wed Jun 6 02:23:27 2007 +--- pam_pkcs11-WS/src/pam_pkcs11/Makefile.in Mon Sep 28 16:06:48 2009 +*************** +*** 234,241 **** + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + MAINTAINERCLEANFILES = Makefile.in +! AM_CFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS) +! AM_CPPFLAGS = -Wall -fno-strict-aliasing $(CRYPTO_CFLAGS) + lib_LTLIBRARIES = pam_pkcs11.la + pam_pkcs11_la_SOURCES = pam_pkcs11.c \ + mapper_mgr.c mapper_mgr.h \ +--- 234,241 ---- + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + MAINTAINERCLEANFILES = Makefile.in +! AM_CFLAGS = $(CRYPTO_CFLAGS) +! AM_CPPFLAGS = $(CRYPTO_CFLAGS) + lib_LTLIBRARIES = pam_pkcs11.la + pam_pkcs11_la_SOURCES = pam_pkcs11.c \ + mapper_mgr.c mapper_mgr.h \ +*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_config.h Wed Jun 6 02:55:02 2007 +--- pam_pkcs11-WS/src/pam_pkcs11/pam_config.h Mon Sep 28 16:06:48 2009 +*************** +*** 13,19 **** + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * +! * $Id: pam_config.h 270 2007-05-21 08:13:00Z ludovic.rousseau $ + */ + + /* +--- 13,19 ---- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * +! * $Id: pam_config.h 341 2008-10-14 07:36:46Z ludovic.rousseau $ + */ + + /* +*************** +*** 38,46 **** +--- 38,48 ---- + char *pkcs11_module; + char *pkcs11_modulepath; + char **screen_savers; ++ char *slot_description; + int slot_num; + int support_threads; + cert_policy policy; ++ char *token_type; + char *username; /* provided user name */ + }; + +*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_pkcs11.c Tue May 22 01:28:33 2007 +--- pam_pkcs11-WS/src/pam_pkcs11/pam_pkcs11.c Mon Nov 2 15:39:57 2009 +*************** +*** 12,18 **** + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * +! * $Id: pam_pkcs11.c 281 2007-05-22 08:28:40Z ludovic.rousseau $ + */ + + /* We have to make this definitions before we include the pam header files! */ +--- 12,18 ---- + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * +! * $Id: pam_pkcs11.c 341 2008-10-14 07:36:46Z ludovic.rousseau $ + */ + + /* We have to make this definitions before we include the pam header files! */ +*************** +*** 59,65 **** + /* + * comodity function that returns 1 on null, empty o spaced string + */ +! int is_spaced_str(const char *str) { + char *pt=(char *)str; + if(!str) return 1; + if (!strcmp(str,"")) return 1; +--- 59,65 ---- + /* + * comodity function that returns 1 on null, empty o spaced string + */ +! static int is_spaced_str(const char *str) { + char *pt=(char *)str; + if(!str) return 1; + if (!strcmp(str,"")) return 1; +*************** +*** 91,103 **** + rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr); + if (rv != PAM_SUCCESS) + return rv; +! if ((resp == NULL) || (resp[0].resp == NULL)) + return !response ? PAM_SUCCESS : PAM_CRED_INSUFFICIENT; + if (response) { + *response = strdup(resp[0].resp); + } + /* overwrite memory and release it */ + memset(resp[0].resp, 0, strlen(resp[0].resp)); + free(&resp[0]); + return PAM_SUCCESS; + } +--- 91,106 ---- + rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr); + if (rv != PAM_SUCCESS) + return rv; +! if ((resp == NULL) || (resp[0].resp == NULL)) { +! free(&resp[0]); + return !response ? PAM_SUCCESS : PAM_CRED_INSUFFICIENT; ++ } + if (response) { + *response = strdup(resp[0].resp); + } + /* overwrite memory and release it */ + memset(resp[0].resp, 0, strlen(resp[0].resp)); ++ free(resp[0].resp); + free(&resp[0]); + return PAM_SUCCESS; + } +*************** +*** 206,211 **** +--- 209,220 ---- + return PAM_AUTHINFO_UNAVAIL; + } + ++ /* Either slot_description or slot_num, but not both, needs to be used */ ++ if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) { ++ ERR("Error setting configuration parameters"); ++ return PAM_AUTHINFO_UNAVAIL; ++ } ++ + /* fail if we are using a remote server + * local login: DISPLAY=:0 + * XDMCP login: DISPLAY=host:0 */ +*************** +*** 274,281 **** + DBG1("explicit username = [%s]", user); + } + } else { +! pam_prompt(pamh, PAM_TEXT_INFO, NULL, +! _("Please insert your smart card or enter your username.")); + /* get user name */ + rv = pam_get_user(pamh, &user, NULL); + +--- 283,292 ---- + DBG1("explicit username = [%s]", user); + } + } else { +! sprintf(password_prompt, +! _("Please insert your %s or enter your username."), +! _(configuration->token_type)); +! pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt); + /* get user name */ + rv = pam_get_user(pamh, &user, NULL); + +*************** +*** 314,321 **** + } + + /* open pkcs #11 session */ +! rv = find_slot_by_number_and_label(ph, configuration->slot_num, + login_token_name, &slot_num); + if (rv != 0) { + ERR("no suitable token available"); + pam_syslog(pamh, LOG_ERR, "no suitable token available"); +--- 325,338 ---- + } + + /* open pkcs #11 session */ +! if (configuration->slot_description != NULL) { +! rv = find_slot_by_slotlabel_and_tokenlabel(ph, +! configuration->slot_description, login_token_name, &slot_num); +! } else if (configuration->slot_num != -1) { +! rv = find_slot_by_number_and_label(ph, configuration->slot_num, + login_token_name, &slot_num); ++ } ++ + if (rv != 0) { + ERR("no suitable token available"); + pam_syslog(pamh, LOG_ERR, "no suitable token available"); +*************** +*** 337,344 **** + pam_prompt(pamh, PAM_TEXT_INFO, NULL, + _("Please insert your smart card.")); + } +! rv = wait_for_token(ph, configuration->slot_num, + login_token_name, &slot_num); + if (rv != 0) { + release_pkcs11_module(ph); + return pkcs11_pam_fail; +--- 354,368 ---- + pam_prompt(pamh, PAM_TEXT_INFO, NULL, + _("Please insert your smart card.")); + } +! +! if (configuration->slot_description != NULL) { +! rv = wait_for_token_by_slotlabel(ph, configuration->slot_description, +! login_token_name, &slot_num); +! } else if (configuration->slot_num != -1) { +! rv = wait_for_token(ph, configuration->slot_num, + login_token_name, &slot_num); ++ } ++ + if (rv != 0) { + release_pkcs11_module(ph); + return pkcs11_pam_fail; +*************** +*** 350,362 **** + } else { + /* we haven't prompted for the user yet, get the user and see if + * the smart card has been inserted in the mean time */ +! pam_prompt(pamh, PAM_TEXT_INFO, NULL, +! _("Please insert your smart card or enter your username.")); + rv = pam_get_user(pamh, &user, NULL); + + /* check one last time for the smart card before bouncing to the next + * module */ +! rv = find_slot_by_number(ph, configuration->slot_num, &slot_num); + if (rv != 0) { + /* user gave us a user id and no smart card go to next module */ + release_pkcs11_module(ph); +--- 374,394 ---- + } else { + /* we haven't prompted for the user yet, get the user and see if + * the smart card has been inserted in the mean time */ +! sprintf(password_prompt, +! _("Please insert your %s or enter your username."), +! _(configuration->token_type)); +! pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt); + rv = pam_get_user(pamh, &user, NULL); + + /* check one last time for the smart card before bouncing to the next + * module */ +! if (configuration->slot_description != NULL) { +! rv = find_slot_by_slotlabel(ph, configuration->slot_description, +! &slot_num); +! } else if (configuration->slot_num != -1) { +! rv = find_slot_by_number(ph, configuration->slot_num, &slot_num); +! } +! + if (rv != 0) { + /* user gave us a user id and no smart card go to next module */ + release_pkcs11_module(ph); +*************** +*** 364,370 **** + } + } + } else { +! pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Smart card inserted. ")); + } + rv = open_pkcs11_session(ph, slot_num); + if (rv != 0) { +--- 396,404 ---- + } + } + } else { +! sprintf(password_prompt, _("Found the %s."), +! _(configuration->token_type)); +! pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt); + } + rv = open_pkcs11_session(ph, slot_num); + if (rv != 0) { +*************** +*** 375,390 **** + } + + /* get password */ +! sprintf(password_prompt, _("Welcome %.32s!"), get_slot_label(ph)); + pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt); + if (configuration->use_first_pass) { + rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0); + } else if (configuration->try_first_pass) { +! rv = pam_get_pwd(pamh, &password, _("Smart card password: "), PAM_AUTHTOK, + PAM_AUTHTOK); + } else { +! rv = pam_get_pwd(pamh, &password, _("Smart card password: "), 0, +! PAM_AUTHTOK); + } + if (rv != PAM_SUCCESS) { + release_pkcs11_module(ph); +--- 409,424 ---- + } + + /* get password */ +! sprintf(password_prompt, _("Welcome %.32s!"), get_slot_tokenlabel(ph)); + pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt); ++ sprintf(password_prompt, _("%s PIN: "), _(configuration->token_type)); + if (configuration->use_first_pass) { + rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0); + } else if (configuration->try_first_pass) { +! rv = pam_get_pwd(pamh, &password, password_prompt, PAM_AUTHTOK, + PAM_AUTHTOK); + } else { +! rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK); + } + if (rv != PAM_SUCCESS) { + release_pkcs11_module(ph); +*************** +*** 558,564 **** + snprintf(env_temp, sizeof(env_temp) - 1, + "PKCS11_LOGIN_TOKEN_NAME=%.*s", + (sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME="), +! get_slot_label(ph)); + rv = pam_putenv(pamh, env_temp); + + if (rv != PAM_SUCCESS) { +--- 592,598 ---- + snprintf(env_temp, sizeof(env_temp) - 1, + "PKCS11_LOGIN_TOKEN_NAME=%.*s", + (sizeof(env_temp) - 1) - strlen("PKCS11_LOGIN_TOKEN_NAME="), +! get_slot_tokenlabel(ph)); + rv = pam_putenv(pamh, env_temp); + + if (rv != PAM_SUCCESS) { +*** pam_pkcs11-0.6.0-ORIG/src/pam_pkcs11/pam_config.c Mon May 21 02:46:19 2007 +--- pam_pkcs11-WS/src/pam_pkcs11/pam_config.c Mon Sep 28 16:06:48 2009 +*************** +*** 20,25 **** +--- 20,26 ---- + + #include + #include ++ #include "config.h" + #include "../scconf/scconf.h" + #include "../common/debug.h" + #include "../common/error.h" +*************** +*** 27,38 **** +--- 28,45 ---- + #include "pam_config.h" + #include "mapper_mgr.h" + ++ #define N_(string) (string) ++ + /* + * configuration related functions + */ + + struct configuration_st configuration = { ++ #ifndef ORIGINAL /* SUN_SOLARIS */ ++ "/etc/security/pam_pkcs11/pam_pkcs11.conf", ++ #else + "/etc/pam_pkcs11/pam_pkcs11.conf", /* char * config_file; */ ++ #endif + NULL, /* scconf_context *ctx; */ + 0, /* int debug; */ + 0, /* int nullok; */ +*************** +*** 44,57 **** + "default", /* const char *pkcs11_module; */ + "/etc/pam_pkcs11/pkcs11_module.so",/* const char *pkcs11_module_path; */ + NULL, /* screen savers */ +! 0, /* int slot_num; */ + 0, /* support threads */ + /* cert policy; */ + { 0,CRLP_NONE,0,"/etc/pam_pkcs11/cacerts","/etc/pam_pkcs11/crls","/etc/pam_pkcs11/nssdb",OCSP_NONE }, + NULL /* char *username */ + }; + +- #if 0 + static void display_config (void) { + DBG1("debug %d",configuration.debug); + DBG1("nullok %d",configuration.nullok); +--- 51,65 ---- + "default", /* const char *pkcs11_module; */ + "/etc/pam_pkcs11/pkcs11_module.so",/* const char *pkcs11_module_path; */ + NULL, /* screen savers */ +! NULL, /* slot_description */ +! -1, /* int slot_num; */ + 0, /* support threads */ + /* cert policy; */ + { 0,CRLP_NONE,0,"/etc/pam_pkcs11/cacerts","/etc/pam_pkcs11/crls","/etc/pam_pkcs11/nssdb",OCSP_NONE }, ++ N_("Smart card"), /* token_type */ + NULL /* char *username */ + }; + + static void display_config (void) { + DBG1("debug %d",configuration.debug); + DBG1("nullok %d",configuration.nullok); +*************** +*** 71,77 **** + DBG1("signature_policy %d",configuration.policy.signature_policy); + DBG1("ocsp_policy %d",configuration.policy.ocsp_policy); + } +- #endif + + /* + parse configuration file +--- 79,84 ---- +*************** +*** 136,143 **** +--- 143,164 ---- + scconf_get_str(pkcs11_mblk,"crl_dir",configuration.policy.crl_dir); + configuration.policy.nss_dir = (char *) + scconf_get_str(pkcs11_mblk,"nss_dir",configuration.policy.nss_dir); ++ configuration.slot_description = (char *) ++ scconf_get_str(pkcs11_mblk,"slot_description",configuration.slot_description); ++ + configuration.slot_num = + scconf_get_int(pkcs11_mblk,"slot_num",configuration.slot_num); ++ ++ if (configuration.slot_description != NULL && configuration.slot_num != -1) { ++ DBG1("Can not specify both slot_description and slot_num in file %s",configuration.config_file); ++ return; ++ } ++ ++ if (configuration.slot_description == NULL && configuration.slot_num == -1) { ++ DBG1("Neither slot_description nor slot_num found in file %s",configuration.config_file); ++ return; ++ } ++ + configuration.support_threads = + scconf_get_bool(pkcs11_mblk,"support_threads",configuration.support_threads); + policy_list= scconf_find_list(pkcs11_mblk,"cert_policy"); +*************** +*** 165,170 **** +--- 186,194 ---- + } + policy_list= policy_list->next; + } ++ ++ configuration.token_type = (char *) ++ scconf_get_str(pkcs11_mblk,"token_type",configuration.token_type); + } + screen_saver_list = scconf_find_list(root,"screen_savers"); + if (screen_saver_list) { +*************** +*** 199,205 **** + int i; + int res; + /* try to find a configuration file entry */ +! for (i = 0; i < argc; i++) { + if (strstr(argv[i],"config_file=") ) { + configuration.config_file=1+strchr(argv[i],'='); + break; +--- 223,229 ---- + int i; + int res; + /* try to find a configuration file entry */ +! for (i = 1; i < argc; i++) { + if (strstr(argv[i],"config_file=") ) { + configuration.config_file=1+strchr(argv[i],'='); + break; +*************** +*** 211,217 **** + /* display_config(); */ + /* finally parse provided arguments */ + /* dont skip argv[0] */ +! for (i = 0; i < argc; i++) { + if (strcmp("nullok", argv[i]) == 0) { + configuration.nullok = 1; + continue; +--- 235,241 ---- + /* display_config(); */ + /* finally parse provided arguments */ + /* dont skip argv[0] */ +! for (i = 1; i < argc; i++) { + if (strcmp("nullok", argv[i]) == 0) { + configuration.nullok = 1; + continue; +*************** +*** 246,255 **** + res=sscanf(argv[i],"pkcs11_module=%255s",configuration.pkcs11_module); + continue; + } + if (strstr(argv[i],"slot_num=") ) { +! res=sscanf(argv[i],"slot_nume=%d",&configuration.slot_num); + continue; + } + if (strstr(argv[i],"ca_dir=") ) { + res=sscanf(argv[i],"ca_dir=%255s",configuration.policy.ca_dir); + continue; +--- 270,285 ---- + res=sscanf(argv[i],"pkcs11_module=%255s",configuration.pkcs11_module); + continue; + } ++ if (strstr(argv[i],"slot_description=") ) { ++ res=sscanf(argv[i],"slot_description=%255s",configuration.slot_description); ++ continue; ++ } ++ + if (strstr(argv[i],"slot_num=") ) { +! res=sscanf(argv[i],"slot_num=%d",&configuration.slot_num); + continue; + } ++ + if (strstr(argv[i],"ca_dir=") ) { + res=sscanf(argv[i],"ca_dir=%255s",configuration.policy.ca_dir); + continue; +*************** +*** 289,294 **** +--- 319,330 ---- + } + continue; + } ++ ++ if (strstr(argv[i],"token_type=") ) { ++ res=sscanf(argv[i],"token_type=%255s",configuration.token_type); ++ continue; ++ } ++ + if (strstr(argv[i],"config_file=") ) { + /* already parsed, skip */ + continue; +*************** +*** 299,302 **** + } + return &configuration; + } +- +--- 335,337 ---- +*** pam_pkcs11-0.6.0-ORIG/src/mappers/ldap_mapper.c Wed Jun 6 02:48:24 2007 +--- pam_pkcs11-WS/src/mappers/ldap_mapper.c Mon Sep 28 16:06:48 2009 +*************** +*** 184,192 **** + } + + # ifdef HAVE_LDAP_INIT +! *ld = ldap_init (uri, defport); + # else +! *ld = ldap_open (uri, defport); + # endif + rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS; + +--- 184,192 ---- + } + + # ifdef HAVE_LDAP_INIT +! *ld = ldap_init (uri, ldapdefport); + # else +! *ld = ldap_open (uri, ldapdefport); + # endif + rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS; + +*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_inspect.c Mon May 21 02:46:19 2007 +--- pam_pkcs11-WS/src/tools/pkcs11_inspect.c Mon Sep 28 16:06:48 2009 +*************** +*** 53,58 **** +--- 53,63 ---- + return 1; + } + ++ if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) { ++ ERR("Error setting configuration parameters"); ++ return 1; ++ } ++ + /* init openssl */ + rv = crypto_init(&configuration->policy); + if (rv != 0) { +*************** +*** 79,85 **** + } + + /* open pkcs #11 session */ +! rv = find_slot_by_number(ph, configuration->slot_num, &slot_num); + if (rv != 0) { + release_pkcs11_module(ph); + DBG("no token available"); +--- 84,95 ---- + } + + /* open pkcs #11 session */ +! if (configuration->slot_description != NULL) { +! rv = find_slot_by_slotlabel(ph, configuration->slot_description, &slot_num); +! } else { +! rv = find_slot_by_number(ph, configuration->slot_num, &slot_num); +! } +! + if (rv != 0) { + release_pkcs11_module(ph); + DBG("no token available"); +*** pam_pkcs11-0.6.0-ORIG/src/tools/pklogin_finder.c Wed Jun 6 03:00:36 2007 +--- pam_pkcs11-WS/src/tools/pklogin_finder.c Mon Sep 28 16:06:48 2009 +*************** +*** 55,60 **** +--- 55,65 ---- + return 1; + } + ++ if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) { ++ ERR("Error setting configuration parameters"); ++ return 1; ++ } ++ + /* init openssl */ + rv = crypto_init(&configuration->policy); + if (rv != 0) { +*************** +*** 80,86 **** + } + + /* open pkcs #11 session */ +! rv = find_slot_by_number(ph,configuration->slot_num, &slot_num); + if (rv != 0) { + release_pkcs11_module(ph); + DBG("no token available"); +--- 85,95 ---- + } + + /* open pkcs #11 session */ +! if (configuration->slot_description != NULL) { +! rv = find_slot_by_slotlabel(ph,configuration->slot_description, &slot_num); +! } else { +! rv = find_slot_by_number(ph,configuration->slot_num, &slot_num); +! } + if (rv != 0) { + release_pkcs11_module(ph); + DBG("no token available"); +*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_eventmgr.c Wed Jun 6 04:14:27 2007 +--- pam_pkcs11-WS/src/tools/pkcs11_eventmgr.c Mon Sep 28 16:06:48 2009 +*************** +*** 430,435 **** +--- 430,436 ---- + } + } + ++ #ifdef HAVE_DAEMON + if (daemonize) { + DBG("Going to be daemon..."); + if ( daemon(0,debug)<0 ) { +*************** +*** 440,445 **** +--- 441,447 ---- + return 1; + } + } ++ #endif + + /* + * Wait endlessly for all events in the list of readers +*************** +*** 512,517 **** +--- 514,520 ---- + } + + /* put my self into background if flag is set */ ++ #ifdef HAVE_DAEMON + if (daemonize) { + DBG("Going to be daemon..."); + if ( daemon(0,debug)<0 ) { +*************** +*** 521,526 **** +--- 524,530 ---- + return 1; + } + } ++ #endif + + /* open pkcs11 sesion */ + DBG("initialising pkcs #11 module..."); +*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_listcerts.c Mon May 21 02:46:19 2007 +--- pam_pkcs11-WS/src/tools/pkcs11_listcerts.c Mon Sep 28 16:06:48 2009 +*************** +*** 53,58 **** +--- 53,63 ---- + return 1; + } + ++ if ((configuration->slot_description != NULL && configuration->slot_num != -1) || (configuration->slot_description == NULL && configuration->slot_num == -1)) { ++ ERR("Error setting configuration parameters"); ++ return 1; ++ } ++ + /* init openssl */ + rv = crypto_init(&configuration->policy); + if (rv != 0) { +*************** +*** 78,84 **** + } + + /* open pkcs #11 session */ +! rv = find_slot_by_number(ph, configuration->slot_num, &slot_num); + if (rv != 0) { + release_pkcs11_module(ph); + DBG("no token available"); +--- 83,94 ---- + } + + /* open pkcs #11 session */ +! if (configuration->slot_description != NULL) { +! rv = find_slot_by_slotlabel(ph,configuration->slot_description, &slot_num); +! } else { +! rv = find_slot_by_number(ph,configuration->slot_num, &slot_num); +! } +! + if (rv != 0) { + release_pkcs11_module(ph); + DBG("no token available"); +*** pam_pkcs11-0.6.0-ORIG/src/tools/pkcs11_setup.c Wed Jun 6 04:20:09 2007 +--- pam_pkcs11-WS/src/tools/pkcs11_setup.c Mon Sep 28 16:06:48 2009 +*************** +*** 60,65 **** +--- 60,92 ---- + return value; + } + ++ #ifndef ORIGINAL /* SUN_SOLARIS */ ++ /* Written by Niels M\ufffd\ufffdller ++ * modified by Ludovic Rousseau ++ * ++ * This file is hereby placed in the public domain. ++ */ ++ static char * strndup (const char *s, size_t size) ++ { ++ char *r; ++ char *end = memchr(s, 0, size); ++ ++ if (NULL == end) ++ return NULL; ++ ++ /* Length */ ++ size = end - s; ++ ++ r = malloc(size+1); ++ if (r) ++ { ++ memcpy(r, s, size); ++ r[size] = '\0'; ++ } ++ return r; ++ } ++ #endif ++ + static int scconf_replace_str_list(scconf_block * block, const char *option, const char *value) + { + scconf_list *list = NULL; +*** pam_pkcs11-0.6.0-ORIG/tools/make_hash_link.sh Mon May 21 02:46:19 2007 +--- pam_pkcs11-WS/tools/make_hash_link.sh Mon Sep 28 16:06:48 2009 +*************** +*** 54,60 **** + hash=`$OPENSSL x509 -inform pem -in $file -noout -hash 2> /dev/null` + if [ ! -z $hash ]; then + is_ca=`$OPENSSL x509 -inform pem -in $file -noout -text | grep 'CA:TRUE'` +! if [ ! -z $is_ca ]; then + hash=$hash. + mk_link + fi +--- 54,60 ---- + hash=`$OPENSSL x509 -inform pem -in $file -noout -hash 2> /dev/null` + if [ ! -z $hash ]; then + is_ca=`$OPENSSL x509 -inform pem -in $file -noout -text | grep 'CA:TRUE'` +! if [ ! -z "$is_ca" ]; then + hash=$hash. + mk_link + fi +*************** +*** 63,69 **** + hash=`$OPENSSL x509 -inform der -in $file -noout -hash 2> /dev/null` + if [ ! -z $hash ]; then + is_ca=`$OPENSSL x509 -inform der -in $file -noout -text | grep 'CA:TRUE'` +! if [ ! -z $is_ca ]; then + hash=$hash. + mk_link + fi +--- 63,69 ---- + hash=`$OPENSSL x509 -inform der -in $file -noout -hash 2> /dev/null` + if [ ! -z $hash ]; then + is_ca=`$OPENSSL x509 -inform der -in $file -noout -text | grep 'CA:TRUE'` +! if [ ! -z "$is_ca" ]; then + hash=$hash. + mk_link + fi