From 4d854689e6bfae16a222284766764647ab235b70 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Wed, 26 Mar 2025 00:46:12 +0800
Subject: [PATCH 1/4] Restore readpassphrase for macOS < 10.12

---
 Makefile                            |   2 +
 src/include/CVS/Entries             |   1 +
 src/include/readpassphrase.h        |  40 ++++++
 src/lib/libc/CVS/Entries.Log        |   1 +
 src/lib/libc/gen/CVS/Entries        |   2 +
 src/lib/libc/gen/CVS/Entries.Static |   0
 src/lib/libc/gen/CVS/Repository     |   1 +
 src/lib/libc/gen/CVS/Root           |   1 +
 src/lib/libc/gen/readpassphrase.c   | 188 ++++++++++++++++++++++++++++
 9 files changed, 236 insertions(+)
 create mode 100644 src/include/readpassphrase.h
 create mode 100644 src/lib/libc/gen/CVS/Entries
 create mode 100644 src/lib/libc/gen/CVS/Entries.Static
 create mode 100644 src/lib/libc/gen/CVS/Repository
 create mode 100644 src/lib/libc/gen/CVS/Root
 create mode 100644 src/lib/libc/gen/readpassphrase.c

diff --git Makefile Makefile
index 84a38e5..1ea5d52 100644
--- Makefile
+++ Makefile
@@ -8,6 +8,7 @@ CVSROOT= anoncvs@anoncvs.openbsd.org:/cvs
 ### sources from upstream
 
 SRCS+= src/lib/libc/crypt/blowfish.c
+SRCS+= src/lib/libc/gen/readpassphrase.c
 SRCS+= src/lib/libc/hash/sha2.c
 SRCS+= src/lib/libc/net/base64.c
 SRCS+= src/lib/libc/string/explicit_bzero.c
@@ -22,6 +23,7 @@ SRCS+= src/usr.bin/signify/sc25519.c
 SRCS+= src/usr.bin/signify/zsig.c
 
 INCL+= src/include/blf.h
+INCL+= src/include/readpassphrase.h
 INCL+= src/include/sha2.h
 INCL+= src/lib/libutil/ohash.h
 INCL+= src/lib/libutil/util.h # only for bcrypt_pbkdf decl
diff --git src/include/CVS/Entries src/include/CVS/Entries
index 431e602..e5a8122 100644
--- src/include/CVS/Entries
+++ src/include/CVS/Entries
@@ -1,3 +1,4 @@
 /blf.h/1.7/Wed Mar 14 17:59:41 2007//
+/readpassphrase.h/1.5/Tue Jun 17 21:56:23 2003//
 /sha2.h/1.10/Sat Sep  3 17:00:29 2016//
 D
diff --git src/include/readpassphrase.h src/include/readpassphrase.h
new file mode 100644
index 0000000..cef36f0
--- /dev/null
+++ src/include/readpassphrase.h
@@ -0,0 +1,40 @@
+/*	$OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $	*/
+
+/*
+ * Copyright (c) 2000, 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#ifndef _READPASSPHRASE_H_
+#define _READPASSPHRASE_H_
+
+#define RPP_ECHO_OFF    0x00		/* Turn off echo (default). */
+#define RPP_ECHO_ON     0x01		/* Leave echo on. */
+#define RPP_REQUIRE_TTY 0x02		/* Fail if there is no tty. */
+#define RPP_FORCELOWER  0x04		/* Force input to lower case. */
+#define RPP_FORCEUPPER  0x08		/* Force input to upper case. */
+#define RPP_SEVENBIT    0x10		/* Strip the high bit from input. */
+#define RPP_STDIN       0x20		/* Read from stdin, not /dev/tty */
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+char * readpassphrase(const char *, char *, size_t, int);
+__END_DECLS
+
+#endif /* !_READPASSPHRASE_H_ */
diff --git src/lib/libc/CVS/Entries.Log src/lib/libc/CVS/Entries.Log
index 91ec17e..afc9c57 100644
--- src/lib/libc/CVS/Entries.Log
+++ src/lib/libc/CVS/Entries.Log
@@ -1,4 +1,5 @@
 A D/crypt////
+A D/gen////
 A D/hash////
 A D/net////
 A D/string////
diff --git src/lib/libc/gen/CVS/Entries src/lib/libc/gen/CVS/Entries
new file mode 100644
index 0000000..f963233
--- /dev/null
+++ src/lib/libc/gen/CVS/Entries
@@ -0,0 +1,2 @@
+/readpassphrase.c/1.25/Mon Sep 14 10:45:27 2015//
+D
diff --git src/lib/libc/gen/CVS/Entries.Static src/lib/libc/gen/CVS/Entries.Static
new file mode 100644
index 0000000..e69de29
diff --git src/lib/libc/gen/CVS/Repository src/lib/libc/gen/CVS/Repository
new file mode 100644
index 0000000..2c0edda
--- /dev/null
+++ src/lib/libc/gen/CVS/Repository
@@ -0,0 +1 @@
+src/lib/libc/gen
diff --git src/lib/libc/gen/CVS/Root src/lib/libc/gen/CVS/Root
new file mode 100644
index 0000000..844b841
--- /dev/null
+++ src/lib/libc/gen/CVS/Root
@@ -0,0 +1 @@
+anoncvs@anoncvs3.usa.openbsd.org:/cvs
diff --git src/lib/libc/gen/readpassphrase.c src/lib/libc/gen/readpassphrase.c
new file mode 100644
index 0000000..3837b08
--- /dev/null
+++ src/lib/libc/gen/readpassphrase.c
@@ -0,0 +1,188 @@
+/*	$OpenBSD: readpassphrase.c,v 1.25 2015/09/14 10:45:27 guenther Exp $	*/
+
+/*
+ * Copyright (c) 2000-2002, 2007, 2010
+ *	Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <readpassphrase.h>
+
+static volatile sig_atomic_t signo[_NSIG];
+
+static void handler(int);
+
+char *
+readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
+{
+	ssize_t nr;
+	int input, output, save_errno, i, need_restart;
+	char ch, *p, *end;
+	struct termios term, oterm;
+	struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
+	struct sigaction savetstp, savettin, savettou, savepipe;
+
+	/* I suppose we could alloc on demand in this case (XXX). */
+	if (bufsiz == 0) {
+		errno = EINVAL;
+		return(NULL);
+	}
+
+restart:
+	for (i = 0; i < _NSIG; i++)
+		signo[i] = 0;
+	nr = -1;
+	save_errno = 0;
+	need_restart = 0;
+	/*
+	 * Read and write to /dev/tty if available.  If not, read from
+	 * stdin and write to stderr unless a tty is required.
+	 */
+	if ((flags & RPP_STDIN) ||
+	    (input = output = open(_PATH_TTY, O_RDWR)) == -1) {
+		if (flags & RPP_REQUIRE_TTY) {
+			errno = ENOTTY;
+			return(NULL);
+		}
+		input = STDIN_FILENO;
+		output = STDERR_FILENO;
+	}
+
+	/*
+	 * Turn off echo if possible.
+	 * If we are using a tty but are not the foreground pgrp this will
+	 * generate SIGTTOU, so do it *before* installing the signal handlers.
+	 */
+	if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
+		memcpy(&term, &oterm, sizeof(term));
+		if (!(flags & RPP_ECHO_ON))
+			term.c_lflag &= ~(ECHO | ECHONL);
+		if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
+			term.c_cc[VSTATUS] = _POSIX_VDISABLE;
+		(void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
+	} else {
+		memset(&term, 0, sizeof(term));
+		term.c_lflag |= ECHO;
+		memset(&oterm, 0, sizeof(oterm));
+		oterm.c_lflag |= ECHO;
+	}
+
+	/*
+	 * Catch signals that would otherwise cause the user to end
+	 * up with echo turned off in the shell.  Don't worry about
+	 * things like SIGXCPU and SIGVTALRM for now.
+	 */
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = 0;		/* don't restart system calls */
+	sa.sa_handler = handler;
+	(void)sigaction(SIGALRM, &sa, &savealrm);
+	(void)sigaction(SIGHUP, &sa, &savehup);
+	(void)sigaction(SIGINT, &sa, &saveint);
+	(void)sigaction(SIGPIPE, &sa, &savepipe);
+	(void)sigaction(SIGQUIT, &sa, &savequit);
+	(void)sigaction(SIGTERM, &sa, &saveterm);
+	(void)sigaction(SIGTSTP, &sa, &savetstp);
+	(void)sigaction(SIGTTIN, &sa, &savettin);
+	(void)sigaction(SIGTTOU, &sa, &savettou);
+
+	if (!(flags & RPP_STDIN))
+		(void)write(output, prompt, strlen(prompt));
+	end = buf + bufsiz - 1;
+	p = buf;
+	while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
+		if (p < end) {
+			if ((flags & RPP_SEVENBIT))
+				ch &= 0x7f;
+			if (isalpha((unsigned char)ch)) {
+				if ((flags & RPP_FORCELOWER))
+					ch = (char)tolower((unsigned char)ch);
+				if ((flags & RPP_FORCEUPPER))
+					ch = (char)toupper((unsigned char)ch);
+			}
+			*p++ = ch;
+		}
+	}
+	*p = '\0';
+	save_errno = errno;
+	if (!(term.c_lflag & ECHO))
+		(void)write(output, "\n", 1);
+
+	/* Restore old terminal settings and signals. */
+	if (memcmp(&term, &oterm, sizeof(term)) != 0) {
+		while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
+		    errno == EINTR && !signo[SIGTTOU])
+			continue;
+	}
+	(void)sigaction(SIGALRM, &savealrm, NULL);
+	(void)sigaction(SIGHUP, &savehup, NULL);
+	(void)sigaction(SIGINT, &saveint, NULL);
+	(void)sigaction(SIGQUIT, &savequit, NULL);
+	(void)sigaction(SIGPIPE, &savepipe, NULL);
+	(void)sigaction(SIGTERM, &saveterm, NULL);
+	(void)sigaction(SIGTSTP, &savetstp, NULL);
+	(void)sigaction(SIGTTIN, &savettin, NULL);
+	(void)sigaction(SIGTTOU, &savettou, NULL);
+	if (input != STDIN_FILENO)
+		(void)close(input);
+
+	/*
+	 * If we were interrupted by a signal, resend it to ourselves
+	 * now that we have restored the signal handlers.
+	 */
+	for (i = 0; i < _NSIG; i++) {
+		if (signo[i]) {
+			kill(getpid(), i);
+			switch (i) {
+			case SIGTSTP:
+			case SIGTTIN:
+			case SIGTTOU:
+				need_restart = 1;
+			}
+		}
+	}
+	if (need_restart)
+		goto restart;
+
+	if (save_errno)
+		errno = save_errno;
+	return(nr == -1 ? NULL : buf);
+}
+DEF_WEAK(readpassphrase);
+
+char *
+getpass(const char *prompt)
+{
+	static char buf[_PASSWORD_LEN + 1];
+
+	return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF));
+}
+
+static void handler(int s)
+{
+
+	signo[s] = 1;
+}
-- 
2.48.0

