Skip to content

Commit

Permalink
node: Improve terminal initialization options.
Browse files Browse the repository at this point in the history
* Allow setting default terminal dimensions, to better support
  environments where 80x24 may not be the norm.
* Prompt users by default for terminal dimensions if not received.
* Don't prompt guests users for info by default if using a TDD.
* mod_smtp_delivery_external: Avoid misleading message about
  message not being delivered securely if STARTTLS is not
  advertised. If implicit TLS was used, this is irrelevant.
  • Loading branch information
InterLinked1 committed Apr 26, 2024
1 parent 71b2cd8 commit 6a28bd6
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 15 deletions.
2 changes: 1 addition & 1 deletion bbs/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ static struct bbs_config *config_parse(const char *name)
continue;
}
#ifdef DEBUG_CONFIG_PARSING
bbs_debug(8, "New key-value pair in %s: %s=%s\n", section->name, keyval->key, keyval->value);
bbs_debug(8, "New key-value pair in %s: %s => %s=%s\n", name, section->name, keyval->key, keyval->value);
#endif
RWLIST_INSERT_TAIL(&section->keyvals, keyval, entry);
bbs_assert(RWLIST_FIRST(&section->keyvals) != NULL);
Expand Down
83 changes: 79 additions & 4 deletions bbs/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "include/user.h"
#include "include/variables.h"
#include "include/term.h"
#include "include/ansi.h"
#include "include/pty.h"
#include "include/menu.h"
#include "include/auth.h"
Expand All @@ -61,10 +62,14 @@ static RWLIST_HEAD_STATIC(nodes, bbs_node);
static unsigned int maxnodes;
static unsigned int minuptimedisplayed = 0;
static int allow_guest = DEFAULT_ALLOW_GUEST;
static int guest_ask_info = DEFAULT_GUEST_ASK_INFO;
static int guest_ask_info = DEFAULT_GUEST_ASK_INFO; /* 0 = don't ask, 1 = ask if not using TDD, 2 = always ask */
static unsigned int defaultbps = 0;
static unsigned int idlemins = 0;

static unsigned int default_cols = 80;
static unsigned int default_rows = 24;
static int ask_dimensions = 1;

static char bbs_name_buf[32] = "BBS"; /* A simple default so this is never empty. */
static char bbs_tagline_buf[84] = "";
static char bbs_hostname_buf[92] = "";
Expand All @@ -73,6 +78,7 @@ static char bbs_exitmsg[484] = "";

static int load_config(void)
{
char tmp[16];
struct bbs_config *cfg = bbs_config_load("nodes.conf", 1); /* Use cached version if possible and not stale */

/* Set some basic defaults, whether there's a config or not */
Expand Down Expand Up @@ -103,9 +109,15 @@ static int load_config(void)
bbs_config_val_set_str(cfg, "bbs", "exitmsg", bbs_exitmsg, sizeof(bbs_exitmsg));
bbs_config_val_set_uint(cfg, "nodes", "maxnodes", &maxnodes);
bbs_config_val_set_uint(cfg, "nodes", "defaultbps", &defaultbps);
bbs_config_val_set_uint(cfg, "nodes", "defaultrows", &default_rows);
bbs_config_val_set_uint(cfg, "nodes", "defaultcols", &default_cols);
bbs_config_val_set_true(cfg, "nodes", "askdimensions", &ask_dimensions);
bbs_config_val_set_uint(cfg, "nodes", "idlemins", &idlemins);
bbs_config_val_set_true(cfg, "guests", "allow", &allow_guest);
bbs_config_val_set_true(cfg, "guests", "askinfo", &guest_ask_info);
if (!bbs_config_val_set_str(cfg, "guests", "askinfo", tmp, sizeof(tmp)) && !strcasecmp(tmp, "always")) {
guest_ask_info = 2;
}

if (!idlemins) {
idlemins = INT_MAX; /* If 0, disable */
Expand Down Expand Up @@ -288,8 +300,8 @@ struct bbs_node *__bbs_node_request(int fd, const char *protname, void *mod)

/* Assume 80x24 terminal by default, for interactive nodes,
* to support dumb terminals over modems that won't tell us their size. */
node->cols = 80;
node->rows = 24;
node->cols = default_cols;
node->rows = default_rows;

/* This prevents this module from being unloaded as long as there are nodes using it.
* For example, since node->protname is constant in this module, if we unload it,
Expand Down Expand Up @@ -1328,7 +1340,7 @@ static int authenticate(struct bbs_node *node)
} else if (!strcasecmp(username, "Guest")) {
if (allow_guest) {
bbs_debug(3, "User continuing as guest\n");
if (guest_ask_info) {
if ((guest_ask_info && !NODE_IS_TDD(node)) || (guest_ask_info == 2)) {
int tries = 4;
char guestname[64], guestemail[64], guestlocation[64];
/* No newlines necessary inbetween reads, since echo is on
Expand Down Expand Up @@ -1898,6 +1910,42 @@ static int ask_yn(struct bbs_node *node, const char *question)
return -1;
}

static int ask_dimension(struct bbs_node *node, const char *question)
{
int i;
ssize_t res;
char buf[16];

for (i = 0; i < 3; i++) {
bbs_node_writef(node, "\n%s? ", question);
res = bbs_node_readline(node, SEC_MS(30), buf, sizeof(buf) - 1);
if (res < 0) {
return -1;
} else if (res) {
int num;
buf[res] = '\0';
num = atoi(buf);
if (!num) {
char buf2[16];
int newlen;
/* Sometimes we read other characters here */
bbs_dump_mem((unsigned char*) buf, (size_t) res);
/* XXX For some reason, the flush prior to calling ask_dimension
* doesn't do what's desired, and we end up reading an escape sequence here.
* So, manually strip that. */
bbs_ansi_strip(buf, (size_t) res, buf2, sizeof(buf2), &newlen);
num = atoi(buf2);
}
if (num <= 0 || num > 1024) {
bbs_debug(3, "Ignoring non-numeric, negative, or invalid response '%s' (%d)\n", buf, num);
continue;
}
return num;
}
}
return -1;
}

static int init_term_properties_manual(struct bbs_node *node)
{
int res;
Expand Down Expand Up @@ -1944,6 +1992,33 @@ static int _bbs_intro(struct bbs_node *node)
res = init_term_query_ansi_escape_support(node);
}

if (!node->dimensions && ask_dimensions) {
/* If the client didn't send us its dimensions automatically,
* prompt the client for dimensions. */
int rows, cols;

/* Eat any responses to previous terminal queries, if they elicited some response */
bbs_node_buffer(node);
bbs_write(node->amaster, "\n", 1); /* Spoof newline to force buffered read to process */
bbs_node_flush_input(node);

cols = ask_dimension(node, "Terminal number of cols");
if (cols <= 0) {
return -1;
} else if (cols < 16) {
/* Unlikely to be a display this small */
bbs_node_writef(node, "Terminal too small, goodbye\n");
return -1;
}
rows = ask_dimension(node, "Terminal number of rows");
if (rows <= 0) {
return -1;
}
node->rows = (unsigned int) rows;
node->cols = (unsigned int) cols;
node->dimensions = 1;
}

bbs_node_buffer(node); /* Reset */
bbs_set_fd_tcp_nodelay(node->sfd, 0); /* Undo the disable */
return 0;
Expand Down
5 changes: 5 additions & 0 deletions configs/nodes.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ maxnodes=64 ; Maximum number of nodes. Once capacity is reached, new connect
;defaultbps=300 ; Throttle node output to a specified speed on connection (bps = bits per second).
; Useful if you want to emulate a lower speed system, but at the cost of less efficient CPU utilization.
; Default is 0 (unthrottled), and input is never throttled.
;defaultrows=24 ; Default number of terminal rows, if not received from client. Default is 24.
;defaultcols=80 ; Default number of terminal columns, if not received from client. Default is 80.
;askdimensions=yes ; Prompt users for their terminal dimensions if they are not received automatically. Default is yes.
idlemins=30 ; The amount of time a user may idle on certain screens before the node is timed out for inactivity.
; Note that some parts of the BBS user their own timers and ignore this setting.
; Default is 30 minutes. Specify 0 for unlimited (disable timeout, at least for prompts that use this timer).

[guests]
allow=yes ; Whether to allow guest logins to the BBS. Default is yes.
askinfo=yes ; Whether to ask guests to provide some basic information about themselves. Default is yes.
; Valid options are 'no', 'yes', and 'always'. 'yes' will ask guests if they are not using a TDD;
; 'always' will prompt users even if they are using a TDD.
; WARNING: If you disable this, guest users will not be able to receive email replies.
22 changes: 12 additions & 10 deletions modules/mod_smtp_delivery_external.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,17 +444,19 @@ static int try_send(struct smtp_session *smtp, struct smtp_tx_data *tx, const ch

tx->prot = "smtp";

if (smtpclient.caps & SMTP_CAPABILITY_STARTTLS) {
if (!secure && bbs_smtp_client_starttls(&smtpclient)) {
goto cleanup; /* Abort if we were told STARTTLS was available but failed to negotiate. */
if (!secure) {
if (smtpclient.caps & SMTP_CAPABILITY_STARTTLS) {
if (bbs_smtp_client_starttls(&smtpclient)) {
goto cleanup; /* Abort if we were told STARTTLS was available but failed to negotiate. */
}
} else if (require_starttls_out) {
bbs_warning("SMTP server %s does not support STARTTLS, but encryption is mandatory. Delivery failed.\n", hostname);
snprintf(buf, len, "STARTTLS not supported");
res = 1;
goto cleanup;
} else if (!bbs_hostname_is_ipv4(hostname) || bbs_ip_is_public_ipv4(hostname)) { /* Don't emit this warning for non-public IPs */
bbs_warning("SMTP server %s does not support STARTTLS. This message will not be transmitted securely!\n", hostname);
}
} else if (require_starttls_out) {
bbs_warning("SMTP server %s does not support STARTTLS, but encryption is mandatory. Delivery failed.\n", hostname);
snprintf(buf, len, "STARTTLS not supported");
res = 1;
goto cleanup;
} else if (!bbs_hostname_is_ipv4(hostname) || bbs_ip_is_public_ipv4(hostname)) { /* Don't emit this warning for non-public IPs */
bbs_warning("SMTP server %s does not support STARTTLS. This message will not be transmitted securely!\n", hostname);
}

if (smtpclient.maxsendsize && (int) (prependlen + writelen) > smtpclient.maxsendsize) {
Expand Down
1 change: 1 addition & 0 deletions tests/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@ static int run_test(const char *filename, int multiple)
modulefp = fopen(TEST_CONFIG_DIR "/nodes.conf", "w");
if (modulefp) {
fprintf(modulefp, "[bbs]\r\nhostname=%s\r\n", TEST_HOSTNAME);
fprintf(modulefp, "[nodes]\r\naskdimensions=no\r\n"); /* Only needed for test_menus */
fclose(modulefp);
}
modulefp = fopen(TEST_CONFIG_DIR "/mod_auth_static.conf", "w");
Expand Down
1 change: 1 addition & 0 deletions tests/test_menus.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ static int pre(void)

/* no net_telnet.conf needed, defaults are sufficient */
TEST_ADD_CONFIG("menus.conf");
TEST_ADD_CONFIG("nodes.conf");

return 0;
}
Expand Down

0 comments on commit 6a28bd6

Please sign in to comment.