debian/0000755000000000000000000000000013631733367007202 5ustar debian/README.Debian0000644000000000000000000000127411330302107011221 0ustar libpam-alreadyloggedin for Debian ================================= To enable the alreadyloggedin module, add the following line to /etc/pam.d/login, just before ``@include common-auth``:: auth sufficient pam_alreadyloggedin.so no_root restrict_tty=/dev/tty[0-9]* restrict_loggedin_tty=/dev/tty[0-9]* Security notes -------------- libpam-alreadyloggedin uses utmp login records to determine whether a user is logged in or not. Terminal locking programs (e.g., vlock) don't remove utmp entries, thus a user would be able to log in without password even if he/she locked all terminals he/she were using. To use vlock along with libpam-alreadyloggedin securely, always use the -a/--all option. debian/changelog0000644000000000000000000000666513631733367011071 0ustar libpam-alreadyloggedin (0.3-8) unstable; urgency=medium * QA upload. * Fix tests for Python3. -- Matthias Klose Tue, 10 Mar 2020 16:49:11 +0100 libpam-alreadyloggedin (0.3-7) unstable; urgency=medium * QA upload. * Properly orphan the package (RFA filed in Nov 2014, orphaned via control message in May 2016). See #770373. * Use python3 in the autopkg test. * Bump debhelper and standards versions. -- Matthias Klose Tue, 10 Mar 2020 10:43:58 +0100 libpam-alreadyloggedin (0.3-6) unstable; urgency=low * Add “XS-Testsuite: autopkgtest” to debian/control. * Improve security warning for the DEP-8 test. -- Jakub Wilk Mon, 24 Feb 2014 22:58:28 +0100 libpam-alreadyloggedin (0.3-5) unstable; urgency=low * Improve the package description. * Improve debian/rules: + Don't use dh_testdir; instead use target dependencies to ensure that debian/rules is run from the correct directory. + Don't assume that build(-arch) was run before binary(-arch). * Use dh-buildinfo: + Update debian/rules. + Add the package to Build-Depends. * Update patch descriptions. * Add patch (manpage-ref-font.diff) to use bold font for manpage references, as recommended by man-pages(7). * Force gzip compression for .debian.tar. * Compile with -D_FILE_OFFSET_BITS=64. * Compile without -DBUG_STAT_MISSING. * Update debian/copyright: + Update format URI. + Bump year range. + Fix formatting of the License field. * Bump standards version to 3.9.5 (no changes needed). * Add DEP-8 tests. -- Jakub Wilk Sat, 22 Feb 2014 22:18:35 +0100 libpam-alreadyloggedin (0.3-4) unstable; urgency=low * Export CFLAGS and CPPFLAGS flags in debian/rules. * Patch upstream makefile to respect *FLAGS from environment. * Bumps standards version to 3.9.2 (no changes needed). * Use versioned format URI for the copyright file. * Rewrite debian/rules without using dh. + Reduce minimum required debhelper version to 7. * Remove Vcs-* fields. -- Jakub Wilk Wed, 28 Sep 2011 18:08:45 +0200 libpam-alreadyloggedin (0.3-3) unstable; urgency=low * Bump standards version to 3.9.1 (no changes needed). * Add Vcs-* fields. * Update my e-mail address. * Update debian/copyright to the latest DEP-5 version. * Update years in debian/copyright. * Revamp debian/rules. + Bump build-dependency on debhelper to (>= 7.0.50) for overrides support. * Pass CFLAGS and LDFLAGS (get from dpkg-buildflags) to the makefile. + Build depend on dpkg-dev (>= 1.15.7). * Refresh patches. * Extract upstream changelog from the RPM spec file. -- Jakub Wilk Fri, 04 Feb 2011 22:33:05 +0100 libpam-alreadyloggedin (0.3-2) unstable; urgency=low * Switch to source format 3.0 (quilt). * Bump standards version to 3.8.3, no changes needed. * Convert debian/copyright to the DEP-5 format. * Don't use MAXPATHLEN constant, as it's not available on Hurd. * Add security notes to package description and README.Debian (closes: #561448). Thanks to Frank Lin PIAT for raising his concerns. * Link using gcc rather than ld. -- Jakub Wilk Tue, 26 Jan 2010 17:29:43 +0100 libpam-alreadyloggedin (0.3-1) unstable; urgency=low * Initial release (Closes: #520108). * Due to #524608, recommend login (>= 1:4.1.3.1-1). -- Jakub Wilk Tue, 12 May 2009 10:19:43 +0200 debian/clean0000644000000000000000000000001211521536642010171 0ustar changelog debian/compat0000644000000000000000000000000213631661020010362 0ustar 9 debian/control0000644000000000000000000000137313631661240010577 0ustar Source: libpam-alreadyloggedin Section: admin Priority: extra Maintainer: Debian QA Group Build-Depends: debhelper (>= 9), dh-buildinfo, dpkg-dev (>= 1.15.7~), libpam0g-dev XS-Testsuite: autopkgtest Standards-Version: 4.5.0 Homepage: http://ilya-evseev.narod.ru/posix/pam_alreadyloggedin/ Package: libpam-alreadyloggedin Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Recommends: login (>= 1:4.1.3.1-1) Description: PAM module to skip password authentication for logged users libpam-alreadloggedin is a PAM module which allows users to skip authentication if they are already logged in on another console. . Note that this module trades a bit of security for users' convenience and thus should be used cautiously. debian/copyright0000644000000000000000000000342212302202675011121 0ustar Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: libpam-alreadyloggedin Upstream-Contact: Ilya Evseev Source: http://ilya-evseev.narod.ru/posix/pam_alreadyloggedin/ Files: * Copyright: 2002 Brian Fundakowski Feldman 2002 Networks Associates Technologies, Inc. License: BSD Files: debian/* Copyright: 2009-2014, Jakub Wilk License: BSD License: BSD Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. . 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. debian/examples0000644000000000000000000000001211521532523010717 0ustar login.sso debian/install0000644000000000000000000000004611521532524010557 0ustar pam_alreadyloggedin.so /lib/security/ debian/manpages0000644000000000000000000000000411521532522010674 0ustar *.8 debian/patches/0000755000000000000000000000000012301642215010611 5ustar debian/patches/makefile.diff0000644000000000000000000000135312301640054013221 0ustar Description: sanitize upstream makefile Author: Jakub Wilk Last-Update: 2014-02-21 --- a/Makefile +++ b/Makefile @@ -10,9 +10,9 @@ RM = rm -f MKDIR = mkdir -p INSTALL = install -#CFLAGS = -c -Wall -O2 -fPIC -I. -CFLAGS = -c $(RPM_OPT_FLAGS) -fPIC -DLINUX_PAM -I. -Wall -DBUG_STAT_MISSING -LDFLAGS = -s -lpam --shared +CFLAGS ?= -g -O2 +CFLAGS += -Wall -fPIC -DLINUX_PAM -I. -DBUG_STAT_MISSING +LDLIBS = -lpam -lc TITLE = pam_alreadyloggedin LIBSHARED = $(TITLE).so @@ -31,10 +31,10 @@ all: $(LIBSHARED) $(LIBSHARED): $(OBJS) - $(LD) $(LDFLAGS) $(OBJS) -o $@ + $(LINK.c) --shared $(LDLIBS) $(OBJS) -o $@ $(TITLE).o: $(TITLE).c - $(CC) $(CFLAGS) $< + $(COMPILE.c) $< install: $(MKDIR) $(FAKEROOT)$(SECUREDIR) debian/patches/manpage-ref-font.diff0000644000000000000000000000106212301640054014567 0ustar Description: use bold font for manpage references man-pages(7) recommends that “any reference to another man page should be written with the name in bold”. However, the mdoc macro package render manpage references with a regular font. This patch fixes this problem. Author: Jakub Wilk Last-Update: 2014-02-21 --- a/pam_alreadyloggedin.8 +++ b/pam_alreadyloggedin.8 @@ -39,6 +39,7 @@ .Dd January 30, 2004 .Dt PAM_ALREADYLOGGEDIN 8 .Os Linux-PAM +.ds Xr-font \f[B] .Sh NAME .Nm pam_alreadyloggedin .Nd Already-logged-in PAM module debian/patches/manpage-typos.diff0000644000000000000000000000236412301640053014232 0ustar Description: fix spelling mistakes in the upstream changelog Author: Jakub Wilk Last-Update: 2014-02-21 --- a/pam_alreadyloggedin.8 +++ b/pam_alreadyloggedin.8 @@ -71,7 +71,7 @@ output, they will generally be allowed to authenticate using this method. .Pp The following options may be passed to the authentication module: -.Bl -tag -width ".Cm restrict_loggedin_tty Ns = Ns Ar ttyfoo*" +.Bl -tag -width ".Cm restrict_loggedin_tty Ns = Ns Ar ttyglob*" .It Cm debug Enable verbose output to syslog at LOG_DEBUG level. .It Cm no_debug @@ -86,9 +86,9 @@ argument is specified as a shell glob, and checked using the .Xr fnmatch 3 function. For example, -.Cm restryct_tty=/dev/tty[1-6] +.Cm restrict_tty=/dev/tty[1-6] allows logging from text consoles of physical terminal only. -.It Cm restrict_loggedin_tty Ns = Ns Ar ttyfoo* +.It Cm restrict_loggedin_tty Ns = Ns Ar ttyglob* Disallow recognition that the user is already logged in unless the terminal device logged in upon matches .Ar ttyglob* . .El @@ -108,9 +108,9 @@ FreeBSD version expects .Pa /dev/ prefix in -.Cm restryct_tty +.Cm restrict_tty value, but value of -.Cm restryct_loggedin_tty +.Cm restrict_loggedin_tty should be without them. Linux version expects .Pa /dev/ debian/patches/maxpathlen.diff0000644000000000000000000000073012301640052013601 0ustar Description: don't use the MAXPATHLEN constant, as it's not available on Hurd Author: Jakub Wilk Last-Update: 2014-02-21 --- a/pam_alreadyloggedin.c +++ b/pam_alreadyloggedin.c @@ -234,7 +234,7 @@ int inutmp(struct utmp *utmp, const char *lineglob, const char *username, uid_t uid) { - char ttypath[MAXPATHLEN]; + char ttypath[sizeof(utmp->ut_line) + sizeof("/dev/")]; struct stat sb; if (utmp->ut_name[0] == '\0' || utmp->ut_line[0] == '\0') debian/patches/series0000644000000000000000000000012512301637471012034 0ustar makefile.diff manpage-typos.diff manpage-ref-font.diff syslog-h.diff maxpathlen.diff debian/patches/syslog-h.diff0000644000000000000000000000052112301640051013202 0ustar Description: add missing include of the syslog.h header Author: Jakub Wilk Last-Update: 2014-02-21 --- a/pam_alreadyloggedin.c +++ b/pam_alreadyloggedin.c @@ -71,6 +71,8 @@ #include #include +#include + /*-------- Reporting ---------*/ #ifdef DEBUG debian/rules0000755000000000000000000000166612301642715010260 0ustar #!/usr/bin/make -f export CFLAGS = $(shell dpkg-buildflags --get CFLAGS) export CPPFLAGS = $(shell dpkg-buildflags --get CPPFLAGS) \ -D_FILE_OFFSET_BITS=64 \ -UBUG_STAT_MISSING \ export LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS) # build* targets # ============== .PHONY: build build-arch build-indep build build-arch: build-stamp build-stamp: debian/control $(MAKE) touch $(@) build-indep: ; # binary* targets # =============== .PHONY: binary binary-arch binary-indep binary binary-arch: build-stamp dh_testroot dh_prep dh_install dh_installdocs dh_buildinfo sed -e '0,/%changelog/d; /## EOF ##/d' < pam_alreadyloggedin.spec > changelog dh_installchangelogs dh_installexamples dh_installman dh_compress dh_fixperms dh_strip dh_shlibdeps dh_installdeb dh_gencontrol dh_md5sums dh_builddeb binary-indep: ; # clean target # ============ .PHONY: clean clean: debian/control $(MAKE) clean dh_clean # vim:ts=4 sw=4 debian/source/0000755000000000000000000000000012301640465010467 5ustar debian/source/format0000644000000000000000000000001411330302107011662 0ustar 3.0 (quilt) debian/source/options0000644000000000000000000000002312301640465012100 0ustar compression = gzip debian/tests/0000755000000000000000000000000013631733367010344 5ustar debian/tests/control0000644000000000000000000000013613631660520011735 0ustar Tests: tests Depends: libpam-alreadyloggedin, python3 Restrictions: breaks-testbed needs-root debian/tests/tests0000755000000000000000000002151313631733367011436 0ustar #!/usr/bin/python3 # encoding=UTF-8 # Copyright © 2014 Jakub Wilk # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # 3. The names of the authors may not be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS “AS IS” AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ''' WARNING ------- This test breaks stuff. Do NOT run it without sufficiently powerful virtualisation. The test does the following changes to the system, which may negatively affect its security: * Change root password. The new password is not guaranteed to be strong. * Add a new (unprivileged) user. * Add pam_alreadyloggedin.so, enabled for /dev/pts/*, to /etc/pam.d/login. * Remove pam_securetty.so from /etc/pam.d/login. An attempt is made to later undo all the above changes, but with no guarantee of success. Additionally: * The test may leave traces of its actions in the syslog. * The test may leave stale utmp entries. (The list of side effects of running this test is not necessarily complete.) ''' import contextlib import errno import os import pty import pwd import random import signal import string import subprocess as ipc import sys rng = random.SystemRandom() class Timeout(RuntimeError): default = 5 def sigalrm_handler(signum, frame): raise Timeout def msg_begin(s, *args, **kwargs): print(s.format(*args, **kwargs), '...', end=' ') def msg_end(s='ok', *args, **kwargs): print(s.format(*args, **kwargs)) msg = msg_end @contextlib.contextmanager def c_pam(): path = '/etc/pam.d/login' msg_begin('create pam.d/login backup') with open(path, 'r') as file: contents = file.readlines() with open(path + '.adt-bak', 'w') as file: for line in contents: file.write(line) msg_end() msg_begin('create new pam.d/login') okmsg = 'ok' with open(path + '.adt-new', 'w') as file: file.write('auth sufficient pam_alreadyloggedin.so no_root restrict_tty=/dev/pts/* restrict_loggedin_tty=/dev/pts/*\n') for line in contents: if line.endswith('pam_securetty.so\n'): okmsg += ' (pam_securetty.so skipped)' continue file.write(line) msg_end(okmsg) try: msg_begin('plant new pam.d/login') os.rename(path + '.adt-new', path) msg_end() yield finally: msg_begin('restore pam.d/login') os.rename(path + '.adt-bak', path) msg_end() def generate_password(): return ''.join( rng.choice( string.letters + string.digits ) for i in range(8) ) def generate_username(): parts = ['adt.'] parts += [rng.choice(string.lowercase) for i in range(8)] return ''.join(parts) def change_password(login, password, already_encrypted=False): msg_begin('change password for {0}', login) cmdline = ['chpasswd'] if already_encrypted: cmdline += ['--encrypted'] child = ipc.Popen(cmdline, stdin=ipc.PIPE) child.stdin.write('{0}:{1}\n'.format(login, password)) child.stdin.close() retcode = child.wait() if retcode: raise ipc.CalledProcessError(retcode, cmdline) msg_end() def add_user(login, password): msg_begin('add user {0}', login) ipc.check_call( ['useradd', '-M', login] ) uid = pwd.getpwnam(login).pw_uid msg_end('uid={0}', uid) change_password(login, password) def delete_user(login): msg_begin('delete user {0}', login) ipc.check_call(['userdel', '-f', login]) msg_end() @contextlib.contextmanager def c_user(): login = generate_username() password = generate_password() add_user(login, password) try: yield (login, password) finally: delete_user(login) def get_encrypted_password(login): msg_begin('get password for {0}', login) line = ipc.check_output( ['getent', 'shadow', login] ) result = line.split(':')[1] msg_end() return result @contextlib.contextmanager def c_root_password(): old_encrypted_password = get_encrypted_password('root') new_password = generate_password() try: change_password('root', new_password) yield new_password finally: change_password('root', old_encrypted_password, already_encrypted=True) @contextlib.contextmanager def c_timeout(timeout=Timeout.default): signal.alarm(timeout) try: yield finally: signal.alarm(0) def pty_expect(fd, expected, timeout=Timeout.default): with c_timeout(timeout=timeout): s = '' while True: try: chunk = os.read(fd, 1024) except OSError as exc: if exc.errno == errno.EIO and not expected: return else: raise for subchunk in chunk.splitlines(): print('| {fd} | {chunk}'.format(fd=fd, chunk=subchunk)) s += chunk if expected in s: break @contextlib.contextmanager def c_fork_login(timeout=Timeout.default): msg_begin('fork pty') pid, fd = pty.fork() if not pid: os.execlp('login', 'login') try: msg_end('pid={0}, fd={1}', pid, fd) yield pid, fd finally: with c_timeout(timeout): msg_begin('waitpid({0})', pid) os.waitpid(pid, 0) msg_end() def main(): msg_begin('getenv(ADTTMP)') if os.getenv('ADTTMP'): msg_end() else: msg_end('unset') msg(__doc__) sys.exit(1) msg_begin('getuid()') if os.getuid() == 0: msg_end('root') else: msg_end('regular user') sys.exit(1) utmp_path = '/var/run/utmp' msg_begin(utmp_path) os.stat(utmp_path) msg_end() msg_begin('reset umask') os.umask(0o022) msg_end() msg_begin('setup SIGALRM handler') signal.signal(signal.SIGALRM, sigalrm_handler) msg_end() with c_pam(): with c_user() as (login, password): test_user(login, password) with c_root_password() as root_password: test_root(root_password) def test_user(login, password): with c_fork_login() as (tty1_pid, tty1): # tty1 pty_expect(tty1, 'login: ') os.write(tty1, login + '\n') pty_expect(tty1, 'Password: ') os.write(tty1, password + '\n') pty_expect(tty1, '$ ') # tty2 with c_fork_login() as (tty2_pid, tty2): pty_expect(tty2, 'login: ') os.write(tty2, login + '\n') pty_expect(tty2, '$ ') os.write(tty2, 'exit\n') pty_expect(tty2, '') # tty1 os.write(tty1, 'exit\n') pty_expect(tty1, '') os.close(tty1) os.close(tty2) with c_fork_login() as (tty1_pid, tty1): pty_expect(tty1, 'login: ') os.write(tty1, login + '\n') pty_expect(tty1, 'Password: ') os.write(tty1, password + '\n') pty_expect(tty1, '$ ') os.write(tty1, 'exit\n') os.close(tty1) def test_root(password): with c_fork_login() as (tty1_pid, tty1): # tty1 pty_expect(tty1, 'login: ') os.write(tty1, 'root\n') pty_expect(tty1, 'Password: ') os.write(tty1, password + '\n') pty_expect(tty1, '# ') # tty2 with c_fork_login() as (tty2_pid, tty2): pty_expect(tty2, 'login: ') os.write(tty2, 'root\n') pty_expect(tty2, 'Password: ') os.write(tty2, password + '\n') pty_expect(tty2, '# ') os.write(tty2, 'exit\n') pty_expect(tty2, '') # tty1 os.write(tty1, 'exit\n') pty_expect(tty1, '') os.close(tty1) os.close(tty2) if __name__ == '__main__': main() # vim:ts=4 sw=4 et debian/watch0000644000000000000000000000014611330302107010206 0ustar version=3 http://ilya-evseev.narod.ru/posix/pam_alreadyloggedin/ pam_alreadyloggedin-(.*)[.]tar[.]gz