Hello,

The "lockscreen" command is still around in screenv5 although it
presently seems to be a nop, presumably because one achieves the
effect through screen -P.

Instead of removing removing lockscreen can you consider reinstating
the old low-fi screen_builtin_lck that prompts for a password (twice),
and locks the screen?  Despite the security holes I feel this could
could be useful screen is compiled without PAM and without root user
(say for installation under ~/.local) without depending on the system.

I'd appreciate if the attached patch could be reviewed. (I haven't
tested it with PAM yet, and it uses ppp->pw_passwd).  The "password"
command has also removed but this patch would work even without it.
Regards, Madhu
>From d4b8782dc1b5bf84a91c85dfef238595644ab027 Mon Sep 17 00:00:00 2001
From: Madhu <enom...@net.meer>
Date: Mon, 2 Oct 2017 10:37:58 +0530
Subject: [PATCH] src/attacher.c: LockScreen with screen_builtin_lck

---
 src/attacher.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/src/attacher.c b/src/attacher.c
index 59eee60..5c1adc9 100644
--- a/src/attacher.c
+++ b/src/attacher.c
@@ -41,9 +41,11 @@
 
 #include "screen.h"
 
+#if 0
 #ifdef ENABLE_PAM
 #include <security/pam_appl.h>
 #endif
+#endif
 
 #include "misc.h"
 #include "socket.h"
@@ -55,6 +57,7 @@ static void AttacherWinch(int);
 static void DoLock(int);
 static void AttachSigCont(int);
 static void AttacherFinitBye(int sigsig) __attribute__((__noreturn__));
+static void screen_builtin_lck(void);
 
 static bool AttacherPanic = false;
 static bool ContinuePlease = false;
@@ -418,6 +421,7 @@ void Attacher(void)
 		}
 		if (LockPlease) {
 			LockPlease = false;
+			screen_builtin_lck();
 			(void)Attach(MSG_CONT);
 		}
 		if (SigWinchPlease) {
@@ -523,3 +527,81 @@ void SendCmdMessage(char *sty, char *match, char **av, int query)
 		close(s);
 	}
 }
+
+static void
+screen_builtin_lck()
+{
+	char fullname[100], *cp1, message[100 + 100];
+	char *pass = 0, mypass[16 + 1], salt[3];
+	pass = ppp->pw_passwd;
+	if (pass == 0 || *pass == 0)
+	{
+		if ((pass = getpass("Key:   ")))
+		{
+			strncpy(mypass, pass, sizeof(mypass) - 1);
+			mypass[sizeof(mypass) - 1] = 0;
+			if (*mypass == 0)
+				return;
+			if ((pass = getpass("Again: ")))
+			{
+				if (strcmp(mypass, pass))
+				{
+					fprintf(stderr, "Passwords don't match.\007\n");
+					sleep(2);
+					return;
+				}
+			}
+		}
+		if (pass == 0)
+		{
+			fprintf(stderr, "Getpass error.\007\n");
+			sleep(2);
+			return;
+		}
+
+		salt[0] = 'A' + (int)(time(0) % 26);
+		salt[1] = 'A' + (int)((time(0) >> 6) % 26);
+		salt[2] = 0;
+		pass = crypt(mypass, salt);
+		if (!pass)
+		{
+			fprintf(stderr, "crypt() error.\007\n");
+			sleep(2);
+			return;
+		}
+		pass = ppp->pw_passwd = SaveStr(pass);
+	}
+
+	strncpy(fullname, ppp->pw_gecos, sizeof(fullname) - 9);
+	fullname[sizeof(fullname) - 9] = 0;
+
+	if ((cp1 = index(fullname, ',')) != NULL)
+		*cp1 = '\0';
+	if ((cp1 = index(fullname, '&')) != NULL)
+	{
+		strncpy(cp1, ppp->pw_name, 8);
+		cp1[8] = 0;
+		if (*cp1 >= 'a' && *cp1 <= 'z')
+			*cp1 -= 'a' - 'A';
+	}
+
+	sprintf(message, "Screen used by %s%s<%s> on %s.\nPassword:\007",
+		fullname, fullname[0] ? " " : "", ppp->pw_name, HostName);
+
+	/* loop here to wait for correct password */
+	for (;;)
+	{
+		errno = 0;
+		if ((cp1 = getpass(message)) == NULL)
+		{
+			AttacherFinit(0);
+			/* NOTREACHED */
+		}
+		char *buf = crypt(cp1, pass);
+		if (buf && !strncmp(buf, pass, strlen(pass)))
+			break;
+		bzero(cp1, strlen(cp1));
+	}
+	bzero(cp1, strlen(cp1));
+}
+
-- 
2.46.0.27.gfa3b914457

Reply via email to