From d9ec9756815cdaf1e29d847702f16fc584e0bc6b Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Debian Linux)" <rob@synchro.net>
Date: Sat, 19 Apr 2025 13:16:41 -0700
Subject: [PATCH] Add -H <password> option, to send specified hashed-password

... rather than a hash of the *user's* password. This allows the local
user to potentially change their password later without invalidating it on
the RLogin server, assuming the RLogin server saves/reuses the specified
password for subsequent authentication (as the Synchronet terminal server
does).

The existing -h option still works as before, but it's a known issue that if
a user changes their password locally, they will no longer be able to
re-authenticate with any RLogin servers they previously created accounts on
using the previous password.

With the -H option, the sysop is instead in control of the password used and
since the resulting hash is from a combination and system and user unique
source data (including optinal salt), as long the same -H password is not used
for multiple 3rd party Rlogin servers, the hashed password should be secure
from capture and reuse on any other RLogin server (or the local server).

While the -h option might be slightly more secure (since a different user
password is likely used for each generated hash), the -H option is less
error-prone and still considered (by me) to be secure from password leaking
and malicious reuse.
---
 exec/rlogin.js | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/exec/rlogin.js b/exec/rlogin.js
index 20c677d7d1..36a07459d6 100644
--- a/exec/rlogin.js
+++ b/exec/rlogin.js
@@ -1,4 +1,4 @@
-// Synchronet RLogin Gateway v2.0
+// Synchronet RLogin Gateway v2.1
 
 // usage: ?rlogin address[:port] [options]
 // options:
@@ -8,7 +8,8 @@
 //   -T <connect-timeout-seconds> (default: 10 seconds)
 //   -m <telnet-gateway-mode> (Number or TG_* vars OR'd together, default: 0)
 //   -p send current user alias and password as server and client-name values
-//   -h[pepper] send current user alias and hashed-password as server and client-name
+//   -h[pepper] send current user alias and hashed-user-password as server and client-name
+//   -H <password> send current user alias and specified hashed-password as server and client-name
 //   -q don't display banner or pause prompt (quiet)
 //   -v increase verbosity (display remote host name/address/port in messages)
 //   -P don't pause for user key-press
@@ -39,9 +40,9 @@ var clear = options.clear === undefined ? true : options.clear;
 var timeout = options.timeout === undefined ? 10 : options.timeout;
 var verbosity = options.verbosity === undefined ? 0 : options.verbosity;
 
-function hashed_user_password(pepper)
+function hashed_password(password, pepper)
 {
-	return sha1_calc(user.security.password
+	return sha1_calc(password
 		+ user.number
 		+ user.stats.firston_date
 		+ (options.salt || system.qwk_id)
@@ -81,8 +82,8 @@ for(var i = 0; i < argv.length; i++) {
 		case 'v':
 			++verbosity;
 			continue;
-		case 'h': // send alias and hashed-password
-			client_name = hashed_user_password(arg.substring(2));
+		case 'h': // send alias and hashed-user-password
+			client_name = hashed_password(user.security.password, arg.substring(2));
 			server_name = user.alias;
 			continue;
 		case 'p': // send alias and password as expected by Synchronet
@@ -107,6 +108,10 @@ for(var i = 0; i < argv.length; i++) {
 		case 'm':
 			mode = eval(value);
 			break;
+		case 'H': // send alias and hashed-password
+			client_name = hashed_password(value, "");
+			server_name = user.alias;
+			continue;
 		default:
 			alert(js.exec_file + ": Unrecognized option: " + arg);
 			exit(1);
-- 
GitLab