pax_global_header00006660000000000000000000000064115731101500014504gustar00rootroot0000000000000052 comment=fc1ea24bb9b02c2d9958daf47d251d5b8fad2397 libpam4j-1.4/000077500000000000000000000000001157311015000130525ustar00rootroot00000000000000libpam4j-1.4/README000066400000000000000000000000311157311015000137240ustar00rootroot00000000000000Java binding for libpam. libpam4j-1.4/pom.xml000066400000000000000000000072571157311015000144020ustar00rootroot00000000000000 4.0.0 org.jvnet.libpam4j libpam4j jar 1.4 Java binding for libpam.so java.net-m2-repository java-net:/maven2-repository~svn/trunk/repository/ scm:svn:https://svn.java.net/svn/libpam4j~svn/tags/libpam4j-1.4 scm:svn:https://svn.java.net/svn/libpam4j~svn/tags/libpam4j-1.4 https://svn.java.net/svn/libpam4j~svn/tags/libpam4j-1.4 The MIT license http://www.opensource.org/licenses/mit-license.php repo maven-compiler-plugin 1.5 1.5 org.jvnet.wagon-svn wagon-svn 1.12 junit junit 3.8.1 test net.java.dev.jna jna 3.2.2 m.g.o-public http://maven.glassfish.org/content/groups/public/ true false m.g.o-public http://maven.glassfish.org/content/groups/public/ true false libpam4j-1.4/src/000077500000000000000000000000001157311015000136415ustar00rootroot00000000000000libpam4j-1.4/src/main/000077500000000000000000000000001157311015000145655ustar00rootroot00000000000000libpam4j-1.4/src/main/java/000077500000000000000000000000001157311015000155065ustar00rootroot00000000000000libpam4j-1.4/src/main/java/org/000077500000000000000000000000001157311015000162755ustar00rootroot00000000000000libpam4j-1.4/src/main/java/org/jvnet/000077500000000000000000000000001157311015000174235ustar00rootroot00000000000000libpam4j-1.4/src/main/java/org/jvnet/libpam/000077500000000000000000000000001157311015000206675ustar00rootroot00000000000000libpam4j-1.4/src/main/java/org/jvnet/libpam/PAM.java000066400000000000000000000146551157311015000221620ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2009, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jvnet.libpam; import org.jvnet.libpam.impl.PAMLibrary.*; import static org.jvnet.libpam.impl.PAMLibrary.*; import org.jvnet.libpam.impl.PAMLibrary.pam_conv.PamCallback; import org.jvnet.libpam.impl.CLibrary.passwd; import static org.jvnet.libpam.impl.CLibrary.libc; import com.sun.jna.Pointer; import static com.sun.jna.Native.POINTER_SIZE; import com.sun.jna.ptr.PointerByReference; import java.util.Set; import java.util.logging.Logger; /** * PAM authenticator. * *

* Instances are thread unsafe and non reentrant. An instace cannot be reused * to authenticate multiple users. * *

* For an overview of PAM programming, refer to the following resources: * *

* * @author Kohsuke Kawaguchi */ public class PAM { private pam_handle_t pht; private int ret; /** * Temporarily stored to pass a value from {@link #authenticate(String, String)} * to {@link pam_conv}. */ private String password; /** * Creates a new authenticator. * * @param serviceName * PAM service name. This corresponds to the service name that shows up * in the PAM configuration, */ public PAM(String serviceName) throws PAMException { pam_conv conv = new pam_conv(new PamCallback() { public int callback(int num_msg, Pointer msg, Pointer resp, Pointer _) { LOGGER.fine("pam_conv num_msg="+num_msg); if(password==null) return PAM_CONV_ERR; // allocates pam_response[num_msg]. the caller will free this Pointer m = libc.calloc(pam_response.SIZE,num_msg); resp.setPointer(0,m); for( int i=0; i getGroupsOfUser(String username) throws PAMException { return new UnixUser(username).getGroups(); } /** * After a successful authentication, call this method to obtain the effective user name. * This can be different from the user name that you passed to the {@link #authenticate(String, String)} * method. */ /** * Performs an early disposal of the object, instead of letting this GC-ed. * Since PAM may hold on to native resources that don't put pressure on Java GC, * doing this is a good idea. * *

* This method is called by {@link #finalize()}, too, so it's not required * to call this method explicitly, however. */ public void dispose() { if(pht!=null) { libpam.pam_end(pht,ret); pht=null; } } @Override protected void finalize() throws Throwable { super.finalize(); dispose(); } private static final Logger LOGGER = Logger.getLogger(PAM.class.getName()); } libpam4j-1.4/src/main/java/org/jvnet/libpam/PAMException.java000066400000000000000000000031351157311015000240300ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2009, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jvnet.libpam; /** * Exception in PAM invoactions. * * @author Kohsuke Kawaguchi */ public class PAMException extends Exception { public PAMException() { } public PAMException(String message) { super(message); } public PAMException(String message, Throwable cause) { super(message, cause); } public PAMException(Throwable cause) { super(cause); } private static final long serialVersionUID = 1L; } libpam4j-1.4/src/main/java/org/jvnet/libpam/UnixUser.java000066400000000000000000000072321157311015000233200ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2009, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jvnet.libpam; import com.sun.jna.Memory; import com.sun.jna.ptr.IntByReference; import static org.jvnet.libpam.impl.CLibrary.libc; import org.jvnet.libpam.impl.CLibrary.passwd; import org.jvnet.libpam.impl.CLibrary.group; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Represents an Unix user. Immutable. * * @author Kohsuke Kawaguchi */ public final class UnixUser { private final String userName; private final int uid,gid; private final Set groups; /*package*/ UnixUser(String userName, passwd pwd) throws PAMException { this.userName = userName; this.uid = pwd.pw_uid; this.gid = pwd.pw_gid; int sz = 4; /*sizeof(gid_t)*/ int ngroups = 64; Memory m = new Memory(ngroups*sz); IntByReference pngroups = new IntByReference(ngroups); try { if(libc.getgrouplist(userName,pwd.pw_gid,m,pngroups)<0) { // allocate a bigger memory m = new Memory(pngroups.getValue()*sz); if(libc.getgrouplist(userName,pwd.pw_gid,m,pngroups)<0) // shouldn't happen, but just in case. throw new PAMException("getgrouplist failed"); } ngroups = pngroups.getValue(); } catch (LinkageError e) { // some platform, notably Solaris, doesn't have the getgrouplist function ngroups = libc._getgroupsbymember(userName,m,ngroups,0); if (ngroups<0) throw new PAMException("_getgroupsbymember failed"); } groups = new HashSet(); for( int i=0; i getGroups() { return Collections.unmodifiableSet(groups); } public static boolean exists(String name) { return libc.getpwnam(name)!=null; } } libpam4j-1.4/src/main/java/org/jvnet/libpam/impl/000077500000000000000000000000001157311015000216305ustar00rootroot00000000000000libpam4j-1.4/src/main/java/org/jvnet/libpam/impl/CLibrary.java000066400000000000000000000064751157311015000242160ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2009, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jvnet.libpam.impl; import com.sun.jna.Pointer; import com.sun.jna.Native; import com.sun.jna.Library; import com.sun.jna.Structure; import com.sun.jna.Memory; import com.sun.jna.ptr.IntByReference; import org.jvnet.libpam.PAMException; /** * @author Kohsuke Kawaguchi */ public interface CLibrary extends Library { /** * Comparing http://linux.die.net/man/3/getpwnam * and my Mac OS X reveals that the structure of this field isn't very portable. * In particular, we cannot read the real name reliably. */ public class passwd extends Structure { /** * User name. */ public String pw_name; /** * Encrypted password. */ public String pw_passwd; public int pw_uid; public int pw_gid; // ... there are a lot more fields public static passwd loadPasswd(String userName) throws PAMException { passwd pwd = libc.getpwnam(userName); if (pwd == null) { throw new PAMException("No user information is available"); } return pwd; } } public class group extends Structure { public String gr_name; // ... the rest of the field is not interesting for us } Pointer calloc(int count, int size); Pointer strdup(String s); passwd getpwnam(String username); /** * Lists up group IDs of the given user. On Linux and most BSDs, but not on Solaris. * See http://www.gnu.org/software/hello/manual/gnulib/getgrouplist.html */ int getgrouplist(String user, int/*gid_t*/ group, Memory groups, IntByReference ngroups); /** * getgrouplist equivalent on Solaris. * See http://mail.opensolaris.org/pipermail/sparks-discuss/2008-September/000528.html */ int _getgroupsbymember(String user, Memory groups, int maxgids, int numgids); group getgrgid(int/*gid_t*/ gid); group getgrnam(String name); // other user/group related functions that are likely useful // see http://www.gnu.org/software/libc/manual/html_node/Users-and-Groups.html#Users-and-Groups public static final CLibrary libc = (CLibrary)Native.loadLibrary("c",CLibrary.class); } libpam4j-1.4/src/main/java/org/jvnet/libpam/impl/PAMLibrary.java000066400000000000000000000111261157311015000244360ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2009, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jvnet.libpam.impl; import com.sun.jna.Library; import com.sun.jna.PointerType; import com.sun.jna.Structure; import com.sun.jna.Pointer; import com.sun.jna.Native; import com.sun.jna.Callback; import com.sun.jna.ptr.PointerByReference; import static org.jvnet.libpam.impl.CLibrary.libc; /** * libpam.so binding. * * See http://www.opengroup.org/onlinepubs/008329799/apdxa.htm * for the online reference of pam_appl.h * * @author Kohsuke Kawaguchi */ public interface PAMLibrary extends Library { class pam_handle_t extends PointerType { public pam_handle_t() {} public pam_handle_t(Pointer pointer) { super(pointer); } } class pam_message extends Structure { public int msg_style; public String msg; /** * Attach to the memory region pointed by the given pointer. */ public pam_message(Pointer src) { useMemory(src); read(); } } class pam_response extends Structure { /** * This is really a string, but this field needs to be malloc-ed by the conversation * method, and to be freed by the caler, so I bind it to {@link Pointer} here. * * The man page doesn't say that, but see * http://www.netbsd.org/docs/guide/en/chap-pam.html#pam-sample-conv * This behavior is confirmed with a test, too; if I don't do strdup, * libpam crashes. */ public Pointer resp; public int resp_retcode; /** * Attach to the memory region pointed by the given memory. */ public pam_response(Pointer src) { useMemory(src); read(); } public pam_response() {} /** * Sets the response code. */ public void setResp(String msg) { this.resp = libc.strdup(msg); } public static final int SIZE = new pam_response().size(); } class pam_conv extends Structure { public interface PamCallback extends Callback { /** * According to http://www.netbsd.org/docs/guide/en/chap-pam.html#pam-sample-conv, * resp and its member string both needs to be allocated by malloc, * to be freed by the caller. */ int callback(int num_msg, Pointer msg, Pointer resp, Pointer _); } public PamCallback conv; public Pointer _; public pam_conv(PamCallback conv) { this.conv = conv; } } int pam_start(String service, String user, pam_conv conv, PointerByReference/* pam_handle_t** */ pamh_p); int pam_end(pam_handle_t handle, int pam_status); int pam_set_item(pam_handle_t handle, int item_type, String item); int pam_get_item(pam_handle_t handle, int item_type, PointerByReference item); int pam_authenticate(pam_handle_t handle, int flags); int pam_acct_mgmt(pam_handle_t handle, int flags); String pam_strerror(pam_handle_t handle, int pam_error); final int PAM_USER = 2; // error code final int PAM_SUCCESS = 0; final int PAM_CONV_ERR = 6; final int PAM_PROMPT_ECHO_OFF = 1; /* Echo off when getting response */ final int PAM_PROMPT_ECHO_ON = 2; /* Echo on when getting response */ final int PAM_ERROR_MSG = 3; /* Error message */ final int PAM_TEXT_INFO = 4; /* Textual information */ public static final PAMLibrary libpam = (PAMLibrary)Native.loadLibrary("pam",PAMLibrary.class); } libpam4j-1.4/src/test/000077500000000000000000000000001157311015000146205ustar00rootroot00000000000000libpam4j-1.4/src/test/java/000077500000000000000000000000001157311015000155415ustar00rootroot00000000000000libpam4j-1.4/src/test/java/org/000077500000000000000000000000001157311015000163305ustar00rootroot00000000000000libpam4j-1.4/src/test/java/org/jvnet/000077500000000000000000000000001157311015000174565ustar00rootroot00000000000000libpam4j-1.4/src/test/java/org/jvnet/libpam/000077500000000000000000000000001157311015000207225ustar00rootroot00000000000000libpam4j-1.4/src/test/java/org/jvnet/libpam/InteractiveTester.java000066400000000000000000000061721157311015000252370ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2009, Sun Microsystems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jvnet.libpam; import junit.framework.TestCase; import java.util.HashSet; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class InteractiveTester extends TestCase { public InteractiveTester(String testName) { super(testName); } public void testPositiveCase() throws Exception { for (int i=0; i<1000; i++) testOne(); } public void testOne() throws Exception { UnixUser u = new PAM("sshd").authenticate(System.getProperty("user.name"), System.getProperty("password")); if(!printOnce) { System.out.println(u.getUID()); System.out.println(u.getGroups()); printOnce = true; } } public void testGetGroups() throws Exception { System.out.println(new PAM("sshd").getGroupsOfUser(System.getProperty("user.name"))); } public void testConcurrent() throws Exception { ExecutorService es = Executors.newFixedThreadPool(10); Set> result = new HashSet>(); for( int i=0; i<1000; i++ ) { result.add(es.submit(new Callable() { public Object call() throws Exception { testOne(); return null; } })); } // wait for completion for (Future f : result) { f.get(); } es.shutdown(); } public void testNegative() throws Exception { try { new PAM("sshd").authenticate("bogus","bogus"); fail("expected a failure"); } catch (PAMException e) { // yep } } public static void main(String[] args) throws Exception { UnixUser u = new PAM("sshd").authenticate(args[0], args[1]); System.out.println(u.getUID()); System.out.println(u.getGroups()); } private boolean printOnce; }