Skip to content
Snippets Groups Projects
Commit 526169c8 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Add option to defer telnet negotiation.

Some BBSs (ms.bsrealm.net) have a mailer running on the initial
socket, and telnet negotiations with that disconnect.  Other
systems could potentially perform the negotiation then fail to
pass the telnet state to the next program.

With the new "Defer Negotiate" telnet option, SyncTERM won't send
any telnet negotiations until it receives a telnet command from
the remote first.
parent 5b2a2bd9
No related branches found
No related tags found
No related merge requests found
Pipeline #8081 passed
......@@ -811,6 +811,7 @@ read_item(str_list_t listfile, struct bbslist *entry, char *bbsname, int id, int
entry->stop_bits = 1;
entry->parity = iniGetEnum(section, NULL, "Parity", parity_enum, SYNCTERM_PARITY_NONE);
entry->telnet_no_binary = iniGetBool(section, NULL, "TelnetBrokenTextmode", false);
entry->defer_telnet_negotiation = iniGetBool(section, NULL, "TelnetDeferNegotiate", false);
/* Log Stuff */
iniGetSString(sys ? NULL : section, NULL, "LogFile", "", entry->logfile, sizeof(entry->logfile));
......@@ -1167,6 +1168,7 @@ enum {
BBSLIST_FIELD_DATA_BITS,
BBSLIST_FIELD_PARITY,
BBSLIST_FIELD_TELNET_NO_BINARY,
BBSLIST_FIELD_TELNET_DEFERED_NEGOTIATION,
};
void
......@@ -1259,6 +1261,10 @@ build_edit_list(struct bbslist *item, char opt[][69], int *optmap, char **opts,
optmap[i] = BBSLIST_FIELD_TELNET_NO_BINARY;
sprintf(opt[i++], "Binmode Broken %s", item->telnet_no_binary ? "Yes" : "No");
}
if (item->conn_type == CONN_TYPE_TELNET || item->conn_type == CONN_TYPE_TELNETS) {
optmap[i] = BBSLIST_FIELD_TELNET_DEFERED_NEGOTIATION;
sprintf(opt[i++], "Defered Negotiate %s", item->defer_telnet_negotiation ? "Yes" : "No");
}
optmap[i] = BBSLIST_FIELD_SCREEN_MODE;
sprintf(opt[i++], "Screen Mode %s", screen_modes[item->screen_mode]);
optmap[i] = BBSLIST_FIELD_FONT;
......@@ -1398,6 +1404,12 @@ build_edit_help(struct bbslist *item, int isdefault, char *helpbuf, size_t hbsz)
hblen += strlcat(helpbuf + hblen, "~ Binmode Broken ~\n"
" Telnet binary mode is broken on the remote system, do not\n"
" enable it when connecting\n\n", hbsz - hblen);
hblen += strlcat(helpbuf + hblen, "~ Defer Negotiate ~\n"
" Some systems have a mailer or other program running on the\n"
" initial connection, and will either disconnect or just ignore\n"
" telnet negotiations at the start of the session. When this\n"
" option is enabled, SyncTERM will wait until it receives a telnet\n"
" command from the remote before starting telnet negotiation.\n\n", hbsz - hblen);
}
hblen += strlcat(helpbuf + hblen, "~ Screen Mode ~\n"
" Display mode to use\n\n", hbsz - hblen);
......@@ -1960,7 +1972,11 @@ edit_list(struct bbslist **list, struct bbslist *item, char *listpath, int isdef
changed = 1;
iniSetBool(&inifile, itemname, "TelnetBrokenTextmode", item->telnet_no_binary, &ini_style);
break;
case BBSLIST_FIELD_TELNET_DEFERED_NEGOTIATION:
item->defer_telnet_negotiation = !item->defer_telnet_negotiation;
changed = 1;
iniSetBool(&inifile, itemname, "TelnetDeferNegotiate", item->defer_telnet_negotiation, &ini_style);
break;
}
if (uifc.changes)
changed = 1;
......@@ -2020,6 +2036,7 @@ add_bbs(char *listpath, struct bbslist *bbs, bool new_entry)
iniSetBool(&inifile, bbs->name, "ForceLCF", bbs->force_lcf, &ini_style);
iniSetBool(&inifile, bbs->name, "YellowIsYellow", bbs->yellow_is_yellow, &ini_style);
iniSetBool(&inifile, bbs->name, "TelnetBrokenTextmode", bbs->telnet_no_binary, &ini_style);
iniSetBool(&inifile, bbs->name, "TelnetDeferNegotiate", bbs->defer_telnet_negotiation, &ini_style);
if (bbs->has_fingerprint) {
char fp[41];
fp[0] = 0;
......
......@@ -93,6 +93,7 @@ enum {
SCREEN_MODE_TERMINATOR
};
enum {
ADDRESS_FAMILY_UNSPEC
,
......@@ -153,6 +154,7 @@ struct bbslist {
uint8_t ssh_fingerprint[20];
bool sftp_public_key;
bool telnet_no_binary;
bool defer_telnet_negotiation;
// No way to get a uint8_t from an ini file.
short unsigned int stop_bits;
short unsigned int data_bits;
......
......@@ -17,6 +17,8 @@
#include "uifcinit.h"
extern int telnet_log_level;
bool telnet_deferred = false;
bool telnet_no_binary = false;
/*****************************************************************************/
......@@ -82,6 +84,22 @@ st_telnet_expand(const uchar *inbuf, size_t inlen, uchar *outbuf, size_t outlen,
return o;
}
void
send_initial_state(void)
{
// Suppress Go Aheads (both directions)
request_telnet_opt(TELNET_WILL, TELNET_SUP_GA);
request_telnet_opt(TELNET_DO, TELNET_SUP_GA);
if (!telnet_no_binary) {
// Enable binary mode (both directions)
request_telnet_opt(TELNET_WILL, TELNET_BINARY_TX);
request_telnet_opt(TELNET_DO, TELNET_BINARY_TX);
}
// Request that the server echos
request_telnet_opt(TELNET_DO, TELNET_ECHO);
telnet_deferred = false;
}
void *
telnet_rx_parse_cb(const void *buf, size_t inlen, size_t *olen)
{
......@@ -90,8 +108,11 @@ telnet_rx_parse_cb(const void *buf, size_t inlen, size_t *olen)
if (ret == NULL)
return ret;
if (telnet_interpret((BYTE *)buf, inlen, ret, olen) != ret)
if (telnet_interpret((BYTE *)buf, inlen, ret, olen) != ret) {
memcpy(ret, buf, *olen);
if (telnet_deferred)
send_initial_state();
}
return ret;
}
......@@ -149,18 +170,13 @@ telnet_connect(struct bbslist *bbs)
conn_api.rx_parse_cb = telnet_rx_parse_cb;
conn_api.tx_parse_cb = telnet_tx_parse_cb;
telnet_deferred = bbs->defer_telnet_negotiation;
telnet_no_binary = bbs->telnet_no_binary;
_beginthread(rlogin_output_thread, 0, NULL);
_beginthread(rlogin_input_thread, 0, bbs);
// Suppress Go Aheads (both directions)
request_telnet_opt(TELNET_WILL, TELNET_SUP_GA);
request_telnet_opt(TELNET_DO, TELNET_SUP_GA);
if (!bbs->telnet_no_binary) {
// Enable binary mode (both directions)
request_telnet_opt(TELNET_WILL, TELNET_BINARY_TX);
request_telnet_opt(TELNET_DO, TELNET_BINARY_TX);
}
// Request that the server echos
request_telnet_opt(TELNET_DO, TELNET_ECHO);
if (!telnet_deferred)
send_initial_state();
if (!bbs->hidepopups)
uifc.pop(NULL);
......
......@@ -6,11 +6,15 @@
#include "sockwrap.h"
extern SOCKET telnet_sock;
extern bool telnet_deferred;
extern bool telnet_no_binary;
void telnet_binary_mode_on(void);
void telnet_binary_mode_off(void);
int telnet_connect(struct bbslist *bbs);
void *telnet_rx_parse_cb(const void *buf, size_t inlen, size_t *olen);
void *telnet_tx_parse_cb(const void *buf, size_t len, size_t *olen);
void send_initial_state(void);
#define telnet_close rlogin_close
......
......@@ -240,22 +240,15 @@ telnets_connect(struct bbslist *bbs)
conn_api.rx_parse_cb = telnet_rx_parse_cb;
conn_api.tx_parse_cb = telnet_tx_parse_cb;
telnet_deferred = bbs->defer_telnet_negotiation;
_beginthread(telnets_output_thread, 0, NULL);
_beginthread(telnets_input_thread, 0, NULL);
if (!bbs->hidepopups)
uifc.pop(NULL); // TODO: Why is this called twice?
// Suppress Go Aheads (both directions)
request_telnet_opt(TELNET_WILL, TELNET_SUP_GA);
request_telnet_opt(TELNET_DO, TELNET_SUP_GA);
if (!bbs->telnet_no_binary) {
// Enable binary mode (both directions)
request_telnet_opt(TELNET_WILL, TELNET_BINARY_TX);
request_telnet_opt(TELNET_DO, TELNET_BINARY_TX);
}
// Request that the server echos
request_telnet_opt(TELNET_DO, TELNET_ECHO);
if (!telnet_deferred)
send_initial_state();
return 0;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment