Skip to content

Instantly share code, notes, and snippets.

@echicken
Last active November 13, 2023 21:09
Show Gist options
  • Save echicken/02aab754cbb497c8a21670b3212e1f09 to your computer and use it in GitHub Desktop.
Save echicken/02aab754cbb497c8a21670b3212e1f09 to your computer and use it in GitHub Desktop.
Synchronet rlogin proxy for automatic newuser creation
/**
* An rlogin proxy script for automatic new user account creation.
* Clients that connect to this service instead of directly to the
* actual rlogin server will have an account created for them if none
* exists.
*
* Put this script in mods/
*
* Add the following block to ctrl/services.ini:
*
* [rlogin-proxy]
* Port = 1513
* Command = rlogin-proxy.js
*
* See ctrl/services.ini for other options.
*
* Port 1513 is just a suggestion, choose whichever one you like. Just make
* sure that it's open to whatever downstream servers want to connect to
* this Synchronet BBS via rlogin.
*
* You may instead set this to listen on port 513, and tell Synchronet to use
* some other port for its actual rlogin server by editing the RLoginPort
* value in the [BBS] section of ctrl/sbbs.ini
*
*/
load('sbbsdefs.js'); // log levels
load('ftelnethelper.js'); // GetRLoginInterface() and GetRLoginPort()
const rh = client.socket.recv(); // Read the rlogin "header" string
if (typeof rh !== 'string') throw new Error('No rlogin header received');
const cs = rh.match(/\x00(.+)\x00(.+)\x00.+\x00/); // Extract client-user-name and server-user-name from header
if (!cs) throw new Error('Invalid rlogin header received: ' + rh);
const username = cs[2];
const password = cs[1];
log(LOG_DEBUG, '"' + username + '" connected to rlogin proxy');
const un = system.matchuser(username); // See if this user exists
if (un === 0) { // User not found
const usr = system.new_user(username, client); // Create the account
if (typeof usr === 'number') { // This has never happened to me
throw new Error('Failed to create new user record for "' + username + '", error: ' + usr);
}
usr.security.password = password; // Apply the password sent in the header
/**
* If you need to set any other user values
* (eg. in order to prevent newuser questions being asked)
* do it here:
*
* usr.name = username;
* usr.netmail = username + '@fake.netmail.host';
* usr.location = 'Place, Holder';
*
* We could get fancy and check the UQ_* values here and do all of that
* automatically, but that's more effort than I want to put in tonight.
* Most game servers probably have all newuser question toggles turned off
* anyway.
*/
log(LOG_INFO, 'rlogin proxy created user account for "' + username + '"');
}
// Connect to the upstream / actual Synchronet rlogin server
const upstreamAddress = GetRLoginInterface();
const upstreamPort = GetRLoginPort();
const upstream = new Socket();
if (!upstream.connect(upstreamAddress, upstreamPort)) {
throw new Error('Failed to connect to upstream rlogin server at ' + upstreamAddress + ':' + upstreamPort);
}
upstream.send(rh); // Forward the initial rlogin "header" string to the upstream server
log(LOG_DEBUG, 'rlogin proxy session established for "' + username + '"');
// If you want to filter out the copyright message for a seamless transition into your game
var filtering = true;
while (client.socket.is_connected && upstream.is_connected && filtering) {
var s = true;
if (upstream.data_waiting) {
s = false;
const fromUpstream = upstream.recv();
const toClient = fromUpstream.replace(/Synchronet.*Swindell/ig, '');
client.socket.send(toClient);
if (toClient !== fromUpstream) filtering = false;
}
if (client.socket.data_waiting) {
s = false;
upstream.send(client.socket.recv());
}
if (s) mswait(1);
}
// Pass all traffic between client and upstream until one of them disconnects
while (client.socket.is_connected && upstream.is_connected) {
var s = true;
if (upstream.data_waiting) {
s = false;
client.socket.send(upstream.recv());
}
if (client.socket.data_waiting) {
s = false;
upstream.send(client.socket.recv());
}
if (s) mswait(1);
}
log(LOG_DEBUG, 'rlogin proxy session terminated for "' + username + '"');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment