libpam-sshauth-0.3.1/0000775000175000017500000000000012165336063014331 5ustar vagrantvagrantlibpam-sshauth-0.3.1/ChangeLog0000644000175000017500000002410312165336063016101 0ustar vagrantvagrant 97 Scott Balneaves 2013-03-26 {libpam-sshauth-0.3.1} Stamp out segfault under KDM 96 Vagrant Cascadian 2013-03-22 {debian/libpam-sshauth_0.3-1} Upload libpam-sshauth 0.3-1 to debian. 95 Vagrant Cascadian 2013-03-15 {libpam-sshauth-0.3} man/waitfor.1: Escape minus signs, otherwise they're rendered as hyphens. 94 Vagrant Cascadian 2013-03-15 debian/rules: Install pam_sshauth.so into /lib//security/. 93 Scott Balneaves 2013-03-14 Succeed for system accounts 92 Vagrant Cascadian 2013-03-12 debian/control: Add Build-Depends on pkg-config. 91 Vagrant Cascadian 2013-03-12 debian/compat: Re-enable compatibility level 9, enabling hardening build flags. 90 Scott Balneaves 2013-03-12 More hardening 89 Scott Balneaves 2013-03-12 Fix for hardening 88 Scott Balneaves 2013-03-12 known_host processing now works; skip over keys we can't handle 87 Scott Balneaves 2013-03-12 working keyboard_interactive, broken known_hosts checking 86 Scott Balneaves 2013-03-12 Revert vagrantc's change; needed to set library variables. Also, added --with-pam-dir variable 85 Vagrant Cascadian 2013-03-11 Set debian/compat to 8, to disable hardening build flags. :( 84 Vagrant Cascadian 2013-03-11 Use AC_CHECK_HEADER with libssh2.h rather than PKG_CHECK_MODULES, otherwise it wouldn't build for me. 83 Vagrant Cascadian 2013-03-11 Add Build-Depends on libssh2-1-dev, drop libssh-dev. 82 Scott Balneaves 2013-03-11 ssh2 keyboard interactive 81 Scott Balneaves 2013-03-11 Initial change to libssh2 80 Scott Balneaves 2013-02-25 updated pammodir. Not working correctly, but this is what its 'supposed' to be 79 Scott Balneaves 2013-02-24 Bump to version 0.3 78 Scott Balneaves 2013-02-24 Move to dir for storage, add waitfor command 77 Scott Balneaves 2013-02-23 Bug in not always returning pam_result 76 Scott Balneaves 2013-02-21 Improve debugging logging 75 Scott Balneaves 2013-02-21 Add pam_sshauth.h to SOURCES so it will be included in a make dist 74 Vagrant Cascadian 2013-02-15 Debian: Update years in debian/copyright. 73 Vagrant Cascadian 2013-02-15 {debian/libpam-sshauth_0.2-1} Upload libpam-sshauth 0.2-1 to Debian experimental. 72 Vagrant Cascadian 2013-02-15 Debian: Add Vcs-Browser and Vcs-Bzr to debian/control. http://bugs.debian.org/692637 71 Vagrant Cascadian 2013-02-15 Debian: Bump Standards-Version to 3.9.4, no changes necessary. 70 Vagrant Cascadian 2013-02-15 Debian: set debian/compat and build-depends on debhelper 9, to enable hardening build flags. 69 Scott Balneaves 2013-02-15 {libpam-sshauth-0.2} More code cleanup; better return values, fixed memory leak, port variable no longer required. 68 Scott Balneaves 2013-02-13 Make packaging match autoconf name 67 Scott Balneaves 2013-02-13 Updated some docs, bumped version to 0.2 66 Scott Balneaves 2013-02-12 Update to build infrastructure 65 Scott Balneaves 2013-02-12 Move to simpler shell based shm_askpass 64 Scott Balneaves 2013-02-12 Implement different askpass functionality 63 Scott Balneaves 2013-02-12 Code cleanup, generalization of env storing routines 62 Scott Balneaves 2013-02-11 More cleanup 61 Scott Balneaves 2013-02-11 Break up into multiple files 60 Scott Balneaves 2012-10-06 Set the environment variables earlier 59 Scott Balneaves 2012-10-06 Very fragile, but now setting environment variables for use with libnss-env so that we can spawn the ssh tunnel as part of the session. 58 Scott Balneaves 2012-10-05 Also handle shadow 57 Scott Balneaves 2012-10-05 Added initial cut of bringing over user geometry from the remote end. Depends on nss_extrausers 56 Scott Balneaves 2012-10-05 Updated README 55 Scott Balneaves 2012-10-05 Clean up some of the ltsp-session handling because of nss_sshsock library; properly handle PAM_XDISPLAY variable. 54 Scott Balneaves 2012-10-01 Removed some code in the example, as the libnss_sshsock NSS module can now be used instead. 53 vagrant@freegeek.org 2011-10-28 {debian/libpam-sshauth_0.1-1} added debian dir for initial packaging. 52 Scott Balneaves 2011-10-28 {libpam-sshauth-0.1} Added shm_askpass manual page 51 Scott Balneaves 2011-10-28 Added try_first_pass functionality 50 Scott Balneaves 2011-09-29 Moved both hostname and port to using pam_set/get_data routines. 49 Scott Balneaves 2011-08-03 Fixed some potential buffer overflows, some code refactoring, addes syslog support to shm_askpass 48 Scott Balneaves 2011-07-19 Quick code audit revealed a missing return value test. Also cleaned up some unneeded initializers. 47 Scott Balneaves 2011-07-13 Integrated the chown as part of the shm_askpass program, making it dependent on some pam variables. Simplifies the code, and makes things more secure. 46 Scott Balneaves 2011-07-11 Added a test for daemon in the example script 45 Scott Balneaves 2011-07-11 Made some cleanups to the session script 44 Scott Balneaves 2011-04-05 Removed flarp from the EXTRA_DIST line in the extras dir. 43 Scott Balneaves 2011-04-05 Removed ChangeLog: bzr log gives history, and the makefile hooks create ChangeLog before a dist. 42 Scott Balneaves 2011-04-05 Removed the pamtest program: libpam-dotfiles provides it, if you'd like to test, or now that libpam_sshauth is becoming stable, just test it in place. 41 Scott Balneaves 2011-04-04 added some ignores 40 Scott Balneaves 2011-04-04 Added authtries parameter, moved to setting the port via the string value, and not atoi()'ing it, remove the display variable handling, set STRICTHOSTKEYCHECK if available 39 Scott Balneaves 2011-03-30 Added manpage, updated changelog 38 Scott Balneaves 2011-03-30 Add handling for starting the tunnel twice: once as root, second time as user. 37 Scott Balneaves 2011-03-30 Add in --chown function to shm_askpass so that root may change ownership for the user. 36 Scott Balneaves 2011-03-29 Handle both /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts 35 Scott Balneaves 2011-03-28 Move to using the /etc/ssh/ssh_known_hosts file, shorten prompts to better fit on screen 34 Scott Balneaves 2011-03-28 Fixed up a couple of errors in ltsp-session 33 Scott Balneaves 2011-03-28 More cleanup in the ltsp-session file. Handle bringing over the shadow file. 32 Scott Balneaves 2011-03-25 Session script now launches socket during auth phase. Pulls across user and group info for nss_extrauser 31 Scott Balneaves 2011-03-25 Added examples directory glue to autoconf, make dist now works correctly 30 Scott Balneaves 2011-03-22 updated some documentation 29 Scott Balneaves 2011-03-21 Properly handle DISPLAY, fix up example session script 28 Scott Balneaves 2011-03-21 Added in the shm_askpass helper, example session files 27 Scott Balneaves 2011-03-20 Remove spawning code: we'll do this with pam_exec. 26 Scott Balneaves 2010-11-19 Spit out an ssh message on failed password, and change a couple more PAM_SSHLIB for PAM_SSHAUTH 25 Scott Balneaves 2010-11-19 Whoops, environment variables should be PAM_SSHAUTH_* 24 Scott Balneaves 2010-11-19 Standardized on either pam_result or ssh_result to indicate which result code I'm dealing with. Refactored do_sshauth code to allow for 3 tries at the password. 23 Scott Balneaves 2010-11-18 Make send-pam-msg a varargs function, so we can format the messages we're sending like printf 22 Scott Balneaves 2010-11-16 Added handling of unknown servers. Will now prompt user via pam mechanism. 21 Scott Balneaves 2010-11-16 Move away from LTSP specific names to pam_sshlib unique names 20 Scott Balneaves 2010-11-15 Zero out password after it's used, so it's not hanging around in memory. 19 Scott Balneaves 2010-11-15 Check more return values, handle command lines. Added debug option 18 Scott Balneaves 2010-11-10 Some cleanup around the password handling, use poll() instead of select(), make sure stderr of ssh's goes to /dev/null as well 17 Scott Balneaves 2010-11-10 Switch to static character array. When we need to exit because of errors, we don't have to worry about freeing character strings. 16 Scott Balneaves 2010-11-08 Add creating socket for public key authentication 15 Scott Balneaves 2010-11-08 Check openpty() return code, some strdups. 14 Scott Balneaves 2010-11-08 Added missing file NEWS, check result of strdup, minor cleanup on the test program 13 Scott Balneaves 2010-11-04 Fix a couple of errors. 12 Scott Balneaves 2010-11-04 Move to pam_syslog so we don't have to manage openlog and closelog 11 Scott Balneaves 2010-11-04 Some cleanup. Lots more work to do: need to parse command lines, check more error codes, etc. 10 Scott Balneaves 2010-10-30 Full implementation at hackfest; first cut 9 Scott Balneaves 2010-01-13 Why not just use syslog directly? 8 Scott Balneaves 2010-01-13 Generalized some functions, added proper port support 7 Scott Balneaves 2010-01-11 Fixed some errors 6 Scott Balneaves 2010-01-11 Added public key authentication method 5 Scott Balneaves 2010-01-10 Updated README with some useful instructions 4 Scott Balneaves 2010-01-10 Little more logging 3 Scott Balneaves 2010-01-10 First success 2 Scott Balneaves 2010-01-10 More work, added initial libssh functionality 1 Scott Balneaves 2010-01-09 Initial commit: laying out some infrastructure libpam-sshauth-0.3.1/README0000664000175000017500000001076212165336063015217 0ustar vagrantvagrantpam_sshauth =========== pam_sshauth is a PAM library that allows you to authenticate a local machine based on being able to ssh into a remote one. It essentially ties a local pam login to a remote ssh login. Requirements: ------------- pam_sshauth requires: * libssh version 4 or better Configuration: -------------- The pam_sshauth module understands 6 pam command line options: * host= * port= * nostrict * authtries= * try_first_pass * shm_askpass So, in the pam file for the service you're using pam_sshauth with, you could specify: auth required pam_sshauth.so host=myhost.com port=128 nostrict The "nostrict" option allows the pam_sshauth module, upon ssh'ing into a host you don't currently have the host key for, to ask you, via the pam prompts mechanism, if you'd like to add the current host to your host keys. The default is that this option will not be offered to you, and any attempt to authenticate against a machine you don't have the host key for will fail. The shm_askpass option will cause the pam module to work with the ssh ASKPASS helper shm_askpass. The pam_sshauth module will ALSO check for the presence of two environment variables: PAM_SSHAUTH_HOST and PAM_SSHAUTH_PORT. It isn't necessary on either the pam command line OR the environment variable to set the port: it will default to 22. However, if neither the pam command host= parameter or the PAM_SSHAUTH_HOST environment variable are set, the authentication will fail. The pam_sshauth module can handle password expiry, via ssh's "kbint" (keyboard interactive) method of authentication. It will detect if the authentication server's sshd supports this option. By default, sshd comes configured with simple password authentication. If you'd like password expiry to work, you need to set: ChallengeResponseAuthentication yes in your /etc/ssh/sshd_config file on the server. Interactions with ssh: ---------------------- One of the primary goals with pam_sshauth is to create an ssh "Master socket" which can thereafter be used to launch programs on the remote system. The pam_sshauth library contains no method to do this directly, for the sake of simplicity. Rather, we provide a helper which can be used via the SSH-ASKPASS mechanism, as well as an example script which can be used in conjunction with pam_exec to create the tunnel. The shm_askpass program is an SSH-ASKPASS compliant shell script. In the examples directory of this archive I've provided an example session script for use with pam_exec which will handle storing the password, launching the ssh Master socket, and closing the socket down on pam session completion. Testing: -------- To test, create an example service file in /etc/pam.d. You can use the "pamtester" utility available at pamtester.sourceforge.net. The service file should contain the following lines: auth required pam_sshauth.so host=127.0.0.1 # or wherever auth required pam_exec.so expose_authtok /usr/bin/ltsp-session session required pam_exec.so /usr/bin/ltsp-session Copy the "examples/ltsp-session" file to /usr/bin, or somewhere else if you'd prefer, and just modify the pam_exec lines above accordingly. Build the source with: ./configure --prefix=/usr && make && sudo make install Then, using pamtester utility: pamtester service user authenticate open_session close_session You should see something along the lines of: sbalneav@eris:~$ pamtester flarp sbalneav authenticate open_session close_session Password: pamtester: successfully authenticated pamtester: sucessfully opened a session pamtester: session has successfully been closed. pam_sshauth logs to authlog: Jan 10 21:29:40 phobos pam_sshauth[22724]: Beginning authentication. Jan 10 21:29:40 phobos pam_sshauth[22724]: User: scbal Host 127.0.0.1 Jan 10 21:29:40 phobos pam_sshauth[22724]: Auth method PASSWORD Jan 10 21:29:40 phobos pam_sshauth[22724]: Auth method INTERACTIVE Jan 10 21:29:40 phobos pam_sshauth[22724]: Performing keyboard interactive authentication Jan 10 21:29:45 phobos sshd[22725]: Accepted keyboard-interactive/pam for scbal from 127.0.0.1 port 56984 ssh2 Jan 10 21:29:45 phobos sshd[22725]: pam_unix(sshd:session): session opened for user scbal by (uid=0) Jan 10 21:29:45 phobos sshd[22783]: Received disconnect from 127.0.0.1: 11: Bye Bye Jan 10 21:29:45 phobos sshd[22725]: pam_unix(sshd:session): session closed for user scbal LICENSE ------- pam_sshauth is licensed under the GNU GPL 2 or later license. (C) 2010-2013 Scott Balneaves libpam-sshauth-0.3.1/NEWS0000664000175000017500000000040512165336063015027 0ustar vagrantvagrantlibpam_sshauth is a pam module that will allow you to authenticate via a remote ssh machine, as well as establish an SSH tunnel. libpam_sshauth can use either password, public key, or challenge-response SSH login methods to authenticate, or establish a tunnel. libpam-sshauth-0.3.1/Makefile.am0000664000175000017500000000044712165336063016372 0ustar vagrantvagrantAUTOMAKE_OPTIONS = dist-bzip2 DISTCLEANFILES = ChangeLog EXTRA_DIST = autogen.sh SUBDIRS = src examples man scripts .PHONY: ChangeLog dist-up ChangeLog: bzr log > ChangeLog || touch ChangeLog dist-hook: ChangeLog #dist-up: dist # ncftpput upload.sourceforge.net incoming $(distdir).tar.bz2 libpam-sshauth-0.3.1/COPYING0000664000175000017500000004312212165336063015366 0ustar vagrantvagrant GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, 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 or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program. 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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) 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; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, 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 executable. However, as a special exception, the source code 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. If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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. 5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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 to this License. 7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program. 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. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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. 9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 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 Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. 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 program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. libpam-sshauth-0.3.1/autogen.sh0000775000175000017500000000004712165336063016333 0ustar vagrantvagrant#!/bin/sh autoreconf --force --install libpam-sshauth-0.3.1/AUTHORS0000664000175000017500000000004412165336063015377 0ustar vagrantvagrantScott Balneaves libpam-sshauth-0.3.1/configure.ac0000664000175000017500000000175112165336063016623 0ustar vagrantvagrantAC_INIT([libpam-sshauth], [0.3], [sbalneav@ltsp.org]) AC_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/pam_sshauth.c]) AC_PREREQ([2.59]) AC_PROG_CC AC_PROG_CC_STDC AM_PROG_CC_C_O AC_CHECK_HEADER([security/pam_modules.h], , [AC_MSG_ERROR([PAM headers missing])]) AC_CHECK_LIB(pam, pam_start, [PAM_LIBS="-lpam"], AC_MSG_ERROR([PAM library missing])) AC_SUBST(PAM_LIBS) AC_SUBST(PAMDIR, "\$(exec_prefix)/lib/security") AC_ARG_WITH(pam-dir, AC_HELP_STRING([--with-pam-dir=DIR], [Where to install PAM module [[PREFIX/lib/security]]]), [case "${withval}" in /*) PAMDIR="${withval}";; ./*|../*) AC_MSG_ERROR(Bad value for --with-pam-dir);; *) PAMDIR="\$(exec_prefix)/lib/${withval}";; esac]) AC_MSG_NOTICE([PAM installation path $PAMDIR]) PKG_CHECK_MODULES([SSH2], [libssh2]) AC_CONFIG_FILES([Makefile] [src/Makefile] [examples/Makefile] [man/Makefile] [scripts/Makefile]) AC_OUTPUT libpam-sshauth-0.3.1/src/0000775000175000017500000000000012165336063015120 5ustar vagrantvagrantlibpam-sshauth-0.3.1/src/pam_util.c0000664000175000017500000001222512165336063017100 0ustar vagrantvagrant/* * pam_sshauth: PAM module for authentication via a remote ssh server. * Copyright (C) 2010-2013 Scott Balneaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include #include "pam_sshauth.h" /* * pam_cleanup * * String cleanup function. */ void pam_cleanup (pam_handle_t * pamh, void * data, int error_status) { free (data); } /* * pam_debug * * Log a message if debug active. */ void pam_debug (pam_handle_t * pamh, const char *format, ...) { char msgbuf[BUFSIZ]; va_list ap; if (psadebug) { va_start (ap, format); if (vsnprintf (msgbuf, sizeof msgbuf, format, ap) >= sizeof msgbuf) { /* * Message was truncated. Make sure we're NULL terminated */ msgbuf[(sizeof msgbuf) - 1] = '\0'; } pam_syslog (pamh, LOG_INFO, "%s", msgbuf); va_end (ap); } } /* * Send a message through pam's conv stack. * * for PAM_TEXT_INFO, and PAM_ERROR_MSG messages. */ int send_pam_msg (pam_handle_t * pamh, int style, const char *format, ...) { char msgbuf[BUFSIZ]; const struct pam_message mymsg = { .msg_style = style, .msg = msgbuf, }; const struct pam_message *msgp = &mymsg; const struct pam_conv *pc; struct pam_response *resp; int pam_result; va_list ap; /* * Start our varargs list, so we can format our message. */ va_start (ap, format); if (vsnprintf (msgbuf, sizeof msgbuf, format, ap) >= sizeof msgbuf) { /* * Message was truncated. Make sure we're NULL terminated, * and log an error. */ msgbuf[(sizeof msgbuf) - 1] = '\0'; pam_syslog (pamh, LOG_ERR, "send_pam_msg () truncated a message."); } va_end (ap); pam_result = pam_get_item (pamh, PAM_CONV, (const void **) &pc); if (pam_result != PAM_SUCCESS) { return pam_result; } if (!pc || !pc->conv) { return PAM_CONV_ERR; } return pc->conv (1, &msgp, &resp, pc->appdata_ptr); } /* * pam_process_args * * Process pam module command line arguments, and set global flags. */ void pam_process_args (pam_handle_t * pamh, int argc, const char **argv, char **host, char **port) { int i; psadebug = 0; nostrict = 0; askpass = 0; try_first_pass = 0; for (i = 0; i < argc; i++) { if (!strcmp (argv[i], "debug")) { psadebug++; } else if (!strcmp (argv[i], "nostrict")) { nostrict++; } else if (!strcmp (argv[i], "shm_askpass")) { askpass++; } else if (!strcmp (argv[i], "try_first_pass")) { try_first_pass++; } else if (!strncmp (argv[i], "authtries=", 10)) { authtries = atoi ((char *)(argv[i] + 10)); /* authtries=x */ } else if (!strncmp (argv[i], "host=", 5)) { *host = (char *)(argv[i] + 5); /* host=foo.bar.com */ } else if (!strncmp (argv[i], "port=", 5)) { *port = (char *)(argv[i] + 5); /* port=x */ } } } int sshauth_pam_env (pam_handle_t * pamh, char *envname, char *envvalue, int cleanup) { /* * Process the var */ if (envvalue && *envvalue != '\0') { char *new_env; size_t len; int pam_result; if (cleanup) { pam_result = pam_set_data (pamh, envname, envvalue, pam_cleanup); } else { pam_result = pam_set_data (pamh, envname, envvalue, NULL); } if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't store %s in pam handle.", envname); return pam_result; } /* * Export envname as pam environment variable for scripts to use. */ len = strlen (envname) + strlen (envvalue) + 2; /* Length of env name + value + 2 for =, NULL */ if ((new_env = (char *) malloc (len)) == NULL) { pam_syslog (pamh, LOG_ERR, "Could not allocate memory for %s variable.", envname); return PAM_BUF_ERR; } snprintf (new_env, len, "%s=%s", envname, envvalue); pam_result = pam_putenv (pamh, new_env); free (new_env); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Could not set %s in pam environment.", envname); } return pam_result; } else { return PAM_SUCCESS; } } libpam-sshauth-0.3.1/src/pam_sshauth.h0000664000175000017500000000451512165336063017612 0ustar vagrantvagrant/* * pam_sshauth: PAM module for authentication via a remote ssh server. * Copyright (C) 2010 Scott Balneaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define HOST "PAM_SSHAUTH_HOST" #define PORT "PAM_SSHAUTH_PORT" #define SSHAUTHDIR "PAM_SSHAUTH_DIR" #define PAMXDISPLAY "PAM_XDISPLAY" #define NOCLEANUP 0 #define CLEANUP 1 #define UID_MIN 500 #define SSH_AUTH_METHOD_PASSWORD 1 #define SSH_AUTH_METHOD_INTERACTIVE 2 #define SSH_AUTH_METHOD_PUBLICKEY 4 #define SSH_AUTH_SUCCESS 0 #define SSH_AUTH_ERROR 1 #define SYSTEM_KNOWNHOSTS "/etc/ssh/ssh_known_hosts" #define AUTHTRIES 3 /* Three chances to get password right */ /* * Globals. */ extern int psadebug; /* Debug flag */ extern int nostrict; /* nostrict flag */ extern int authtries; /* Number of times we'll try to authenticate */ extern int try_first_pass; /* Try to obtain auth token from pam stack */ extern int askpass; /* Support shm_askpass */ /* * Prototypes */ void cleanup (pam_handle_t * pamh, void * data, int error_status); void pam_debug (pam_handle_t * pamh, const char *format, ...); int send_pam_msg (pam_handle_t * pamh, int style, const char *format, ...); void pam_process_args (pam_handle_t * pamh, int argc, const char **argv, char **host, char **port); int sshauth_pam_env (pam_handle_t * pamh, char *envname, char *envvalue, int cleanup); int do_sshauth (pam_handle_t * pamh, const char *username); int create_sshauthdir (pam_handle_t * pamh, const char *username); int askpass_create (pam_handle_t * pamh); int askpass_remove (pam_handle_t * pamh); libpam-sshauth-0.3.1/src/pam_sshauth.c0000664000175000017500000001243112165336063017601 0ustar vagrantvagrant/* * pam_sshauth: PAM module for authentication via a remote ssh server. * Copyright (C) 2010-2013 Scott Balneaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* * I met a traveller from an antique land * Who said: `Two vast and trunkless legs of stone * Stand in the desert. Near them, on the sand, * Half sunk, a shattered visage lies, whose frown, * And wrinkled lip, and sneer of cold command, * Tell that its sculptor well those passions read * Which yet survive, stamped on these lifeless things, * The hand that mocked them and the heart that fed. * And on the pedestal these words appear -- * "My name is Ozymandias, king of kings: * Look on my works, ye Mighty, and despair!" * Nothing beside remains. Round the decay * Of that colossal wreck, boundless and bare * The lone and level sands stretch far away.' * * --Percy Bysshe Shelley */ #include #include #include #include #include #include /* * PAM_SM_* define. */ #define PAM_SM_AUTH /* supports Authentication */ #define PAM_SM_SESSION /* supports Session management */ #include #include #include "pam_sshauth.h" /* * Globals. */ int psadebug; /* Debug flag */ int nostrict; /* nostrict flag */ int authtries = AUTHTRIES; /* Number of times we'll try to authenticate */ int try_first_pass; /* Try to obtain auth token from pam stack */ int askpass; /* Support shm_askpass */ /* * Authentication function */ PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) { const char *username; int pam_result; char *host = getenv (HOST); char *port = getenv (PORT); char *display = getenv ("DISPLAY"); struct passwd *pwent; /* * Valid pam handle? */ if (pamh == NULL) { return PAM_SYSTEM_ERR; } /* * Get the username. */ pam_result = pam_get_user (pamh, &username, NULL); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't determine username."); return pam_result; } /* * Is it a system user? Succeed. */ pam_debug (pamh, "username %s", username); if ((pwent = getpwnam (username)) != NULL) { if (pwent->pw_uid < UID_MIN) { return PAM_SUCCESS; } } pam_process_args (pamh, argc, argv, &host, &port); pam_debug (pamh, "Authentication begins."); /* * Process the hostname */ if ((pam_result = sshauth_pam_env (pamh, HOST, host, NOCLEANUP)) != PAM_SUCCESS) { return pam_result; } /* * Process the port */ if ((pam_result = sshauth_pam_env (pamh, PORT, port, NOCLEANUP)) != PAM_SUCCESS) { return pam_result; } /* * Process the DISPLAY. Set PAM_XDISPLAY if applicable. */ if ((pam_result = sshauth_pam_env (pamh, PAMXDISPLAY, display, NOCLEANUP)) != PAM_SUCCESS) { return pam_result; } /* * Create our temp dir. */ pam_result = create_sshauthdir (pamh, username); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't create sshauthdir."); return pam_result; } /* * Perform the authentication. */ pam_result = do_sshauth (pamh, username); pam_debug (pamh, "Authentication finished."); if (pam_result == PAM_SUCCESS && askpass > 0) { pam_debug (pamh, "Handling shm_askpass support."); pam_result = askpass_create (pamh); } return pam_result; } PAM_EXTERN int pam_sm_setcred (pam_handle_t * pamh, int flags, int argc, const char **argv) { return PAM_SUCCESS; } PAM_EXTERN int pam_sm_open_session (pam_handle_t * pamh, int flags, int argc, const char **argv) { return PAM_SUCCESS; } PAM_EXTERN int pam_sm_close_session (pam_handle_t * pamh, int flags, int argc, const char **argv) { int pam_result; const char *username; struct passwd *pwent; char *host, *port; /* * Valid pam handle? */ if (pamh == NULL) { return PAM_SYSTEM_ERR; } /* * Get the username. */ pam_result = pam_get_user (pamh, &username, NULL); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't determine username."); return pam_result; } /* * Is it a system user? Succeed. */ if ((pwent = getpwnam (username)) != NULL) { if (pwent->pw_uid < UID_MIN) { return PAM_SUCCESS; } } pam_process_args (pamh, argc, argv, &host, &port); if (askpass) { return askpass_remove (pamh); } return PAM_SUCCESS; } libpam-sshauth-0.3.1/src/waitfor.c0000664000175000017500000000351212165336063016740 0ustar vagrantvagrant/* * waitfor: small shell helper for waiting for files to appear. * Copyright (C) 2013 Scott Balneaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include /* * waitfor * * Simple program to check for a file either appearing, or disappeating, every * .2 seconds. Optional timeout. returns 1 if timeout, 0 if waited for event * happened. * * No timeout specified = wait indefinitely. */ int main (int argc, char **argv) { int exist = 1; int timeout = 0; const char *path; struct stat statbuf; int c; int st; int count; opterr = 0; while ((c = getopt (argc, argv, "nt:")) != -1) switch (c) { case 'n': exist = 0; break; case 't': timeout = atoi (optarg); break; default: exit (1); } path = argv[optind]; timeout *= 5; for (count = 0; count <= timeout;) { st = stat (path, &statbuf); if (exist && st == 0) { return 0; } if (!exist && st < 0) { return 0; } usleep (200000); if (timeout) { count++; } } return 1; } libpam-sshauth-0.3.1/src/sess_funcs.c0000664000175000017500000000632012165336063017440 0ustar vagrantvagrant/* * pam_sshauth: PAM module for authentication via a remote ssh server. * Copyright (C) 2010-2013 Scott Balneaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pam_sshauth.h" /* * create_sshauthdir * */ int create_sshauthdir (pam_handle_t * pamh, const char *username) { char *dirname; if (asprintf (&dirname, "/tmp/%s.XXXXXX", username) < 0) { pam_syslog (pamh, LOG_ERR, "Couldn't allocate space to store authdir name"); return PAM_BUF_ERR; } if (mkdtemp (dirname) == NULL) { pam_syslog (pamh, LOG_ERR, "Couldn't generate unique store authdir name"); return PAM_BUF_ERR; } return sshauth_pam_env (pamh, SSHAUTHDIR, dirname, CLEANUP); } /* * askpass_create * * Create the secure password file needed by the shm_askpass utility. */ int askpass_create (pam_handle_t * pamh) { char *password; char *authdir; char pw_filename[BUFSIZ]; int pam_result; int f; pam_result = pam_get_data (pamh, SSHAUTHDIR, (const void **)&authdir); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't obtain authdir name from the pam stack."); return pam_result; } sprintf (pw_filename, "%s/.passwd", authdir); pam_result = pam_get_item (pamh, PAM_AUTHTOK, (const void **)&password); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't obtain PAM_AUTHTOK from the pam stack."); return pam_result; } if ((f = creat (pw_filename, S_IRUSR | S_IWUSR)) < 0) { pam_syslog (pamh, LOG_ERR, "Couldn't create tmpfile"); return PAM_SYSTEM_ERR; } write (f, password, strlen (password)); close (f); return PAM_SUCCESS; } /* * askpass_remove * * Remove the password file needed by shm_askpass */ int askpass_remove (pam_handle_t * pamh) { char *authdir; char pw_filename[BUFSIZ]; int pam_result; pam_result = pam_get_data (pamh, SSHAUTHDIR, (const void **)&authdir); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't obtain authdir name from the pam stack."); return pam_result; } sprintf (pw_filename, "%s/.passwd", authdir); if (unlink (pw_filename) < 0) { pam_debug (pamh, "tmpfile already removed."); } return PAM_SUCCESS; } libpam-sshauth-0.3.1/src/Makefile.am0000664000175000017500000000056112165336063017156 0ustar vagrantvagrantbin_PROGRAMS = waitfor pammod_PROGRAMS = pam_sshauth.so pammoddir=$(PAMDIR) waitfor_SOURCES = waitfor.c pam_sshauth_so_SOURCES = pam_sshauth.c pam_util.c auth_funcs.c sess_funcs.c pam_sshauth.h pam_sshauth_so_CFLAGS = -fpic -Wall $(GLIB_CFLAGS) $(SSH2_CFLAGS) pam_sshauth_so_LDFLAGS = -shared pam_sshauth_so_LDADD = $(PAM_LIBS) $(SSH2_LIBS) $(GLIB_LIBS) $(UTIL_LIBS) libpam-sshauth-0.3.1/src/auth_funcs.c0000664000175000017500000002527512165336063017436 0ustar vagrantvagrant/* * pam_sshauth: PAM module for authentication via a remote ssh server. * Copyright (C) 2010-2013 Scott Balneaves * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pam_sshauth.h" #define SSH_AUTH_METHOD_PASSWORD 1 #define SSH_AUTH_METHOD_INTERACTIVE 2 #define SSH_AUTH_SUCCESS 0 #define SSH_AUTH_ERROR 1 static void kbd_callback (const char *name, int name_len, const char *instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT * prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE * responses, void **abstract) { pam_handle_t *pamh = *abstract; int i; /* * Get any instructions the ssh session has generted, * and send them to the user via the pam message system. */ if (instruction_len > 0) { send_pam_msg (pamh, PAM_TEXT_INFO, instruction); } /* * Loop through the prompts that ssh has given us, and ask the * user via pam prompts for the answers. */ for (i = 0; i < num_prompts; i++) { int style = prompts[i].echo ? PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF; int pam_retval; char *buf, *response; if ((buf = malloc (prompts[i].length + 1)) == NULL) { return; } strncpy (buf, prompts[i].text, prompts[i].length); *(buf + prompts[i].length) = '\0'; pam_retval = pam_prompt (pamh, style, &response, "%s", buf); free (buf); if (pam_retval != PAM_SUCCESS) { return; } responses[i].text = strdup (response); responses[i].length = strlen (response); if (pam_set_item (pamh, PAM_AUTHTOK, response) != PAM_SUCCESS) { return; } } } /* * auth_pw () * * conduct an ssh simple password based authentication */ static int auth_pw (pam_handle_t * pamh, const char *username, LIBSSH2_SESSION * session) { int ssh_result; char *password = NULL; /* * try_first_pass works with simple password authentication. */ if (try_first_pass) { if (pam_get_item (pamh, PAM_AUTHTOK, (const void **) &password) != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't obtain PAM_AUTHTOK from the pam stack."); password = NULL; } } if (password == NULL) { if (pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &password, "Password:") != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't obtain password from pam_prompt."); return SSH_AUTH_ERROR; } } ssh_result = libssh2_userauth_password (session, username, password); if (ssh_result == SSH_AUTH_SUCCESS) { /* * The very last response we've gotten should be the password. Store it * as the AUTHTOK */ if (!try_first_pass && pam_set_item (pamh, PAM_AUTHTOK, password) != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't store password as PAM_AUTHTOK."); return SSH_AUTH_ERROR; } return ssh_result; } else { char *errmsg; int len; libssh2_session_last_error (session, &errmsg, &len, 0); send_pam_msg (pamh, PAM_TEXT_INFO, errmsg); return ssh_result; } } /* * do_sshauth () * * Authenticate by attempting an ssh connection */ int do_sshauth (pam_handle_t * pamh, const char *username) { int method = 0; int ssh_result = SSH_AUTH_ERROR; int pam_result; int count; int iport; int sockfd = 0; int type; const char *fingerprint = NULL; const char *host; const char *port; char *userauthlist; struct hostent *server; struct sockaddr_in serv_addr; LIBSSH2_SESSION *session = NULL; LIBSSH2_KNOWNHOSTS *nh = NULL; size_t len; FILE *khf; pam_result = pam_get_data (pamh, HOST, (const void **) &host); if (pam_result != PAM_SUCCESS) { pam_syslog (pamh, LOG_ERR, "Couldn't retrieve hostname from pam handle."); return pam_result; } pam_result = pam_get_data (pamh, PORT, (const void **) &port); if (pam_result != PAM_SUCCESS) { /* Couldn't retrieve port. Fallback to 22 */ iport = 22; } else { iport = atoi (port); } /* * Establish our socket */ sockfd = socket (AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { pam_syslog (pamh, LOG_ERR, "Couldn't create socket."); return PAM_SYSTEM_ERR; } server = gethostbyname (host); if (server == NULL) { pam_syslog (pamh, LOG_ERR, "Couldn't resolve hostname %s.", host); return PAM_SYSTEM_ERR; } bzero ((char *) &serv_addr, sizeof serv_addr); serv_addr.sin_family = AF_INET; bcopy ((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons (iport); if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof serv_addr) < 0) { pam_syslog (pamh, LOG_ERR, "Couldn't connect to %s.", host); return PAM_SYSTEM_ERR; } /* * Begin the authentication loop. Loop until we're successfully * authenticated, or AUTHTRIES times, whichever comes first. */ count = authtries; session = libssh2_session_init_ex (NULL, NULL, NULL, (void *) pamh); if (session == NULL) { pam_syslog (pamh, LOG_ERR, "Couldn't allocate ssh session structure for host %s", host); goto fail; } /* * tell libssh2 we want communications to use blocking */ libssh2_session_set_blocking (session, 1); /* * Start the connection. */ if (libssh2_session_handshake (session, sockfd) != 0) { pam_syslog (pamh, LOG_ERR, "Couldn't handshake ssh session."); goto fail; } nh = libssh2_knownhost_init (session); if (!nh) { pam_syslog (pamh, LOG_ERR, "Couldn't allocate known_host structure."); goto fail; } pam_debug (pamh, "Connected to host %s", host); /* * Load known hosts from the system file. */ khf = fopen (SYSTEM_KNOWNHOSTS, "r"); if (khf) { char buf[2048]; while (fgets (buf, sizeof (buf), khf)) { if (libssh2_knownhost_readline (nh, buf, strlen (buf), LIBSSH2_KNOWNHOST_FILE_OPENSSH)) { /* Skip over any keys libssh2 doesn't support */ continue; } } fclose (khf); } /* * Obtain our hosts fingerprint. */ fingerprint = libssh2_session_hostkey (session, &len, &type); /* * Is this server known to us? Try our /etc/ssh/ssh_known_hosts file * first. */ if (fingerprint) { int check = libssh2_knownhost_check (nh, host, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW, NULL); if (check == LIBSSH2_KNOWNHOST_CHECK_FAILURE) { goto fail; } if ((check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND) && nostrict) { char *response = NULL; /* * Unknown server. Ask the user, via the pam prompts, if they'd * like to connect. */ pam_debug (pamh, "Server not in known_hosts file."); send_pam_msg (pamh, PAM_TEXT_INFO, "Server unknown. Trust?"); pam_prompt (pamh, PAM_PROMPT_ECHO_ON, &response, "Type 'yes' to continue: "); if (!response || (strncasecmp (response, "yes", 3) != 0)) { pam_debug (pamh, "User does not trust host."); goto fail; } } else if ((check == LIBSSH2_KNOWNHOST_CHECK_NOTFOUND) && !nostrict) { pam_debug (pamh, "Unknown server and strict host checking. Connection denied."); send_pam_msg (pamh, PAM_TEXT_INFO, "Server is unknown, and strict checking enabled. Connection denied."); goto fail; } else if (check == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { pam_debug (pamh, "Host key for %s changed. Connection terminated.", host); pam_syslog (pamh, LOG_ERR, "Host key for %s changed.", host); send_pam_msg (pamh, PAM_TEXT_INFO, "Server's host key has changed."); send_pam_msg (pamh, PAM_TEXT_INFO, "Possible man-in-the-middle attack. Connection terminated."); goto fail; } } /* * Find out what methods the ssh server supports for authentication. */ userauthlist = libssh2_userauth_list (session, username, strlen (username)); /* * List auth methods that have been returned. */ pam_debug (pamh, "Authentication methods supported: %s", userauthlist); if (strstr (userauthlist, "password") != NULL) { method |= SSH_AUTH_METHOD_PASSWORD; } if (strstr (userauthlist, "keyboard-interactive") != NULL) { method |= SSH_AUTH_METHOD_INTERACTIVE; } do { /* * Try keyboard interactive next, if supported. */ if (method & SSH_AUTH_METHOD_INTERACTIVE) { /* * SSH_AUTH_METHOD_INTERACTIVE requires * ChallengeResponseAuthentication to be set to "yes" * in /etc/ssh/sshd_config. */ pam_debug (pamh, "Trying keyboard interactive authentication."); ssh_result = libssh2_userauth_keyboard_interactive (session, username, &kbd_callback); if (ssh_result == SSH_AUTH_SUCCESS) { break; } } /* * Finally, plain password authentication. */ if (method & SSH_AUTH_METHOD_PASSWORD) { /* * SSH_AUTH_METHOD_PASSWORD is simpler, and * won't handle password expiry. */ pam_debug (pamh, "Trying simple password authentication."); ssh_result = auth_pw (pamh, username, session); if (ssh_result == SSH_AUTH_SUCCESS) { break; } } count--; } while (count); fail: if (nh != NULL) { libssh2_knownhost_free (nh); } if (session != NULL) { libssh2_session_disconnect (session, "Shutdown"); libssh2_session_free (session); libssh2_exit (); } if (sockfd) { close (sockfd); } if (ssh_result == SSH_AUTH_SUCCESS) { pam_debug (pamh, "Authenticated successfully."); return PAM_SUCCESS; } else { pam_debug (pamh, "Authentication failed."); return PAM_AUTH_ERR; } } libpam-sshauth-0.3.1/scripts/0000775000175000017500000000000012165336063016020 5ustar vagrantvagrantlibpam-sshauth-0.3.1/scripts/shm_askpass0000775000175000017500000000030412165336063020257 0ustar vagrantvagrant#!/bin/sh [ -z "${PAM_SSHAUTH_DIR}" ] && exit 1 PASSWORD=$(cat "${PAM_SSHAUTH_DIR}/.passwd") echo "${PASSWORD}" ID=$(id -u) if [ "${ID}" != "0" ]; then rm "${PAM_SSHAUTH_DIR}/.passwd" fi libpam-sshauth-0.3.1/scripts/Makefile.am0000664000175000017500000000003712165336063020054 0ustar vagrantvagrantdist_bin_SCRIPTS = shm_askpass libpam-sshauth-0.3.1/man/0000775000175000017500000000000012165336063015104 5ustar vagrantvagrantlibpam-sshauth-0.3.1/man/waitfor.10000664000175000017500000000152112165336063016640 0ustar vagrantvagrant.TH "WAITFOR" "1" "2013/02/24" .nh .ad l .SH "NAME" waitfor \- wait for a file action, with timeout. .SH "SYNOPSIS" .HP \w'\fBwaitfor\&.so\fR\ 'u \fBwaitfor\fR [\-t \fIseconds\fR] [\-n] file .SH "DESCRIPTION" .PP \fBwaitfor\fR will wait for a file to appear, or with the \-n option, for a file to disappear\&. If a timeout is provided, with the [\-t] option, if the file action doesn't happen within the time specified, the program will exit\&. .PP .SH "RETURN VALUES" .PP The program will return 0 if the file action happens\&. If no timeout is specified, \fBwaitfor\fR will wait forever\&. If a timeout is specified, and the file action does not happen within the timeout specified, \fBwaitfor\fR will return 1\&. .PP .SH "SEE ALSO" .PP \fBpam_sshauth\fR(8), .SH "AUTHOR" .PP waitfor was written by Scott Balneaves \&. libpam-sshauth-0.3.1/man/shm_askpass.10000664000175000017500000000115012165336063017477 0ustar vagrantvagrant.TH "SHM_ASKPASS" "1" "2013/02/13" .nh .ad l .SH "NAME" shm_askpass \- An SSH-ASKPASS compliant helper for use with pam_sshauth .SH "SYNOPSIS" .HP \w'\fBshm_askpass\fR\ 'u \fBshm_askpass\fR .SH "DESCRIPTION" .PP \fBshm_askpass\fR is a small SSH-ASKPASS compliant password helper\&. Upon providing the password to ssh as a regular user, it will automatically delete the password\&. If it provides the password as root, it will not clear the password\&. .PP .SH "SEE ALSO" .PP \fBpam_sshauth\fR(8), \fBpam.d\fR(5), \fBpam\fR(7) .SH "AUTHOR" .PP shm_askpass was written by Scott Balneaves \&. libpam-sshauth-0.3.1/man/pam_sshauth.80000664000175000017500000000610212165336063017510 0ustar vagrantvagrant.TH "PAM_SSHAUTH" "8" "2013/02/13" .nh .ad l .SH "NAME" pam_sshauth \- PAM module which authenticates against an ssh server .SH "SYNOPSIS" .HP \w'\fBpam_sshauth\&.so\fR\ 'u \fBpam_sshauth\&.so\fR [debug] [nostrict] [shm_askpass] [authtries=\fItries\fR] [try_first_pass] [host=\fIhost\fR] [port=\fIport\fR] .SH "DESCRIPTION" .PP pam_sshauth is a PAM module that can be used to authenticate a user based on whether they can ssh into an external machine\&. It is written using sshlib\&. .PP The following PAM environment list variables are set by the module: \fIPAM_SSHAUTH_HOST\fR and \fIPAM_SSHAUTH_PORT\fR\&. Both of these reflect what was passed on the PAM command line to the module\&. .PP The module will attempt to initiate an SSH session with the host specified\&. It will support public-key, simple password, and keyboard-interactive authentication methods\&. Note that, in order for keyboard-interactive methods to work, the SSH server must have enabled \fIChallengeResponseAuthentication\fR in it's configuration\&. This would be needed if you'd like the \fBpam_sshauth\fR module to handle password expiry messages when talking to the SSH server\&. .PP .SH "OPTIONS" .PP .PP \fBdebug\fR .RS 4 Log debug information to syslog\&. The LOG_AUTH facility is used\&. .RE .PP \fBnostrict\fR .RS 4 If contacting a host for which we don't have an entry in known_hosts, ask, via the pam prompts, if you'd like to trust this host, and add it to your known_hosts file\&. The default will be to fail the authentication\&. .RE .PP \fBshm_askpass\fR .RS 4 Properly handle interaction with the ASKPASS helper shm_askpass to allow you to spawn ssh sockets\&. .RE .PP \fBhost=\fR\fB\fIhost\fR\fR .RS 4 Specifies the host we're to authenticate with\&. .RE .PP \fBport=\fR\fB\fIport\fR\fR .RS 4 Specifies the port we're to contact the remote ssh server on (if not specified, it defaults to 22)\&. .RE .PP \fBauthtries=\fR\fB\fInum\fR\fR .RS 4 Specifies the number of times we will try to authenticate\&. Defaults to 3\&. Note that this is only the number of times \fBpam_sshauth\fR will try\&. If the SSH server has a smaller number specified via MaxAuthTries, \fBpam_sshauth\fR will not override that\&. .RE .PP \fBtry_first_pass\fR .RS 4 Use the authentication token previously obtained by another module in the pam stack\&. If the token cannot be obtained, the \fBpam_sshauth\fR will prompt for a password\&. .RE .PP .SH "MODULE TYPES PROVIDED" .PP Only the \fBauth\fR module type is provided\&. .SH "RETURN VALUES" .PP .PP PAM_SUCCESS .RS 4 The user authenticated successfully\&. .RE .PP PAM_AUTH_ERR .RS 4 The user did not authenticate successfully\&. .RE .PP PAM_SYSTEM_ERR .RS 4 A system error occurred in establishing the ssh connection to the host specified\&. Check the syslog for details\&. .RE .SH "EXAMPLES" .PP For an authentication line: .sp .if n \{\ .RS 4 .\} .nf auth required pam_sshauth\&.so debug nostrict host=192.168.0.254 port=22 .fi .if n \{\ .RE .\} .SH "SEE ALSO" .PP \fBpam.conf\fR(5), \fBpam.d\fR(5), \fBpam\fR(7) .SH "AUTHOR" .PP pam_sshauth was written by Scott Balneaves \&. libpam-sshauth-0.3.1/man/Makefile.am0000664000175000017500000000006612165336063017142 0ustar vagrantvagrantdist_man_MANS = pam_sshauth.8 shm_askpass.1 waitfor.1 libpam-sshauth-0.3.1/examples/0000775000175000017500000000000012165336063016147 5ustar vagrantvagrantlibpam-sshauth-0.3.1/examples/Makefile.am0000664000175000017500000000003212165336063020176 0ustar vagrantvagrantEXTRA_DIST = ltsp-session libpam-sshauth-0.3.1/examples/ltsp-session0000775000175000017500000000413212165336063020540 0ustar vagrantvagrant#!/bin/sh SOCKETDIR="/tmp" SOCKET="${SOCKETDIR}/${PAM_USER}-${PAM_XDISPLAY}" export DISPLAY=${PAM_XDISPLAY} export SSH_ASKPASS="/usr/bin/shm_askpass" test -x /usr/bin/daemon || exit 1 print_env () { logger "PAM_USER=${PAM_USER}" logger "PAM_SSHAUTH_HOST=${PAM_SSHAUTH_HOST}" logger "SOCKET=${SOCKET}" logger "DISPLAY=${DISPLAY}" W=$(whoami) logger "whoami: ${W}" } open_socket () { if [ -n "${DISPLAY}" ]; then # # We have a $DISPLAY variable set. Spawn an ssh session. # Note, you must install the "daemon" package to obtain the "daemon" # utility. This nice little program easily backgrounds any script or # command, and has the added advantage (for us) of disassociating from # the controlling terminal. With no controlling terminal, and $DISPLAY # set, ssh will use the program specified in SSH_ASKPASS to obtain the # passowrd. Since this was stored in the "auth" phase above, # shm_askpass will pass it to ssh for it to authenticate with. # daemon -i -- ssh -q -N -X -M -S "${SOCKET}" -l ${PAM_USER} ${PAM_SSHAUTH_HOST} fi } close_socket () { ssh -q -S "${SOCKET}" -O exit ${PAM_SSHAUTH_HOST} } # # This is an example session helper script to be used in conjunction with # pam_exec and libpam_sshauth. # case ${PAM_TYPE} in auth) logger "___ Begin Auth ___" print_env # # We're authenticating, so we'll store the auth token using shm_askpass # shm_askpass --write will read a password from stdin, and store it in # POSIX shared memory. # shm_askpass --write logger "___ End Auth ___" ;; open_session) logger "___ Begin Open_Session ___" print_env # # opening a session as user. Spawn our ssh socket, this time as the # user. # open_socket logger "___ End Open_Session ___" ;; close_session) # # We're closing the session down, so cause the socket to exit. # logger "___ Begin Close_Session ___" print_env close_socket logger "___ End Close_Session ___" ;; esac exit 0