====== Terminal Server ======
The Synchronet //Terminal Server// is responsible for providing that "old school" BBS user interface over dial-up modems and classic Internet console protocols (e.g. Telnet).

===== Features =====

  * Supports ANSI X3.64 (color and monochrome), PETSCII, [[wp>Remote_imaging_protocol|RIP]], and dumb terminals
  * Supports [[wp>ASCII|US-ASCII]], [[wp>Code_page_437|CP437]] (a.k.a. IBM Extended ASCII), UTF-8 (UNICODE), and CBM/[[wp>PETSCII]] character sets 
  * Supported Protocols: [[#Telnet]], [[#RLogin]], [[#SSH]], and raw TCP

===== Configure =====

The Synchronet Terminal Server can be configured via [[util:SCFG]]:Servers->Terminal Server:

  ╔═══════════════════════════════════════════╗
  ║          Terminal Server Settings         ║
  ╠═══════════════════════════════════════════╣
  ║ │Enabled                       Yes        ║
  ║ │Log Level                     Info       ║
  ║ │Serving Nodes                 1-4        ║
  ║ │SSH Support...                Port 22    ║
  ║ │Telnet Support...             Port 23    ║
  ║ │RLogin Support...             Port 513   ║
  ║ │40 Column PETSCII Support     Port 64    ║
  ║ │80 Column PETSCII Support     Port 128   ║
  ║ │DOS Program Support           Yes        ║
  ║ │Max Concurrent Connections    Unlimited  ║
  ║ │Max Dumb Login Inactivity     1 minute   ║
  ║ │Max User Login Inactivity     10 minutes ║
  ║ │Max New User Inactivity       1 hour     ║
  ║ │Max User Inactivity           10 minutes ║
  ║ │Output Buffer Drain Timeout   10 ms      ║
  ║ │Execute Timed Events          Yes        ║
  ║ │Execute QWK-related Events    Yes        ║
  ║ │Event Log Level               Info       ║
  ║ │Lookup Client Hostname        Yes        ║
  ║ │Login Requirements                       ║
  ║ │JavaScript Settings...                   ║
  ║ │Failed Login Attempts...                 ║
  ╚═══════════════════════════════════════════╝

The //Max Concurrent Connections// submenu caps the simultaneous unauthenticated connections a single client IP can hold open, and (optionally) auto-filters IPs that repeatedly bump into that limit — see [[howto:block-hackers#concurrent_connection_auto-filtering|Concurrent Connection Auto-Filtering]]:

  ╔══════════════════════════════════════════════════════════╗
  ║                Max Concurrent Connections                ║
  ╠══════════════════════════════════════════════════════════╣
  ║ │Maximum (Unauthenticated)     Unlimited                 ║
  ║ │Auto-Filter Threshold         Disabled                  ║
  ║ │Auto-Filter Duration          1 day                     ║
  ║ │Auto-Filter Silently          No                        ║
  ╚══════════════════════════════════════════════════════════╝

... or configured (on Windows) via [[monitor:SBBSCTRL]]:Telnet->Configure dialog

{{:server:sbbsctrl.3.20.term.config.png}}

... or configured by manually editing the ''[BBS]'' section of the ''[[dir:ctrl]]/[[config:sbbs.ini]]'' file

===== Key Bindings =====

==== Global Ctrl-Keys ====

These control-key combinations have special purpose at almost any-time while using the Terminal Server:

^ Ctrl-Key ^ Description ^
| Ctrl-K   | Display a Ctrl-key Menu |
| Ctrl-C   | Stop the current process / listing / operation |
| Ctrl-O   | Toggle auto-pause prompt temporarily |
| Ctrl-Z   | Toggle raw input/output mode |
| Ctrl-U   | List users online |
| Ctrl-P   | Page for chat or send instant-message or telegram to users |
| Ctrl-T   | Display current time information |

Global control-keys are handled in sbbs_t::handle_ctrlkey(), called from sbbs_t::inkey() in ''inkey.cpp'' and exposed in JavaScript via console.inkey().

Global control key handling may be disabled/re-enabled (per key) programmatically via the JavaScript console.ctrlkey_passthru property:
	js.on_exit("console.ctrlkey_passthru = " + console.ctrlkey_passthru);
	console.ctrlkey_passthru|=(1<<16);      // Disable Ctrl-P handling in sbbs

Custom global control-key handlers may be installed via [[util:SCFG]]->External Programs->Global Hot Key Events:

  ╔═══════════════════════════════════════════╗
  ║           Global Hot Key Events           ║
  ╠═══════════════════════════════════════════╣
  ║ │Ctrl-P    ?privatemsg.js                 ║
  ║ │Ctrl-U    ?nodelist.js -active           ║
  ║ │                                         ║
  ╚═══════════════════════════════════════════╝
==== Line Input ====

Additional control-key combinations have special behavior during line (text string) input:

^ Ctrl-Key ^ Description ^
| Ctrl-N   | Move to next word in line |
| Ctrl-\   | Move to previous word in line |
| Ctrl-D   | Delete word to the right |
| Ctrl-W   | Delete word to the left |
| Ctrl-Y   | Delete from the cursor to the end of the line |
| Ctrl-X   | Delete the entire current line |
| Ctrl-L   | Center the line and complete input |
| Ctrl-Z   | Undo (revert edited line) |
| Ctrl-R   | Redraw current line |
| Ctrl-A   | Insert an [[custom:ctrl-a_codes|attribute code]] (when allowed) |
| Ctrl-G   | Insert a beep character (when allowed) |

The line/string input control-keys are handled via sbbs_t::getstr() in ''getstr.cpp'' and exposed in JavaScript via console.getstr().

==== Extended Keys ====

The Synchronet Terminal Server endeavors to support most extended-keys (e.g. home, end, arrow-keys, etc.) on most terminals while simultaneously supporting control-key equivalents for all terminals.

^ Extended Key ^ Decimal ^ Hex ^ Ctrl-Key ^ ANSI((ANSI X3.64/ECMA-048 escape sequence)) ^ Other((e.g. VT-220 or XTerm escape sequence)) ^ Description (typical use) ^ 
| Home         | 2       | 02  | Ctrl-B   | \e[H                    | \e[1~  | Move cursor to beginning of line or top of page/list/document |
| End          | 5       | 05  | Ctrl-E   | \e[K and \e[F           | \e[4~  | Move cursor to end of line or bottom of page/list/document |
| Up-arrow     | 30      | 1E  | Ctrl-Caret   | \e[A                    |        | Move cursor up one line or recall previous history item |
| Down-arrow   | 10      | 0A  | Ctrl-J   | \e[B                    |        | Move cursor down one line or recall next history item |
| Left-arrow   | 29      | 1D  | Ctrl-]   | \e[D                    |        | Move cursor to the left |
| Right-arrow  | 6       | 06  | Ctrl-F   | \e[C                    |        | Move cursor to the right |
| Page-up      | 16      | 10  | Ctrl-P   | \e[V                    | \e[5~  | Move cursor up one page |
| Page-down    | 14      | 0E  | Ctrl-N   | \e[U                    | \e[6~  | Move cursor up one page |
| Insert       | 22      | 16  | Ctrl-V   | \e[@                    | \e[2~  | Toggle insert/overwrite text mode |
| Delete       | 127     | 7F  | Ctrl-?   |                         | \e[3~  | Delete character under cursor (delete-right), also Ctrl-Backspace |


===== Telnet =====

[[wp>Telnet]] clients (a.k.a. [[resource:term|terminal programs]]) are supported, by default, on the standard Telnet TCP port: 23.

The Synchronet Terminal Server will negotiate Telnet options with the client (enforcing echo and non-line-at-a-time modes), perform ''IAC'' (character 255) escaping, and CR/LF->CR and CR/NUL->CR translation (when not in //binary mode//).

==== Configure ====
Telnet support in the Synchronet Terminal Server can be configured via [[util:SCFG]]:Servers->Terminal Server->Telnet Support:

  ╔══════════════════════════════════╗
  ║          Telnet Support          ║
  ╠══════════════════════════════════╣
  ║ │Enabled             Yes         ║
  ║ │Interfaces          0.0.0.0, :: ║
  ║ │Port                23          ║
  ║ │Command Debug       No          ║
  ║ │Send Go-Aheads      Yes         ║
  ╚══════════════════════════════════╝

==== Options ====

Telnet options are negotiated between the client and server, normally without any indication to the user.

If no Telnet options are received by the Terminal Server during an initial client session on the configured Telnet port, the Terminal Server will revert the client to just "Raw TCP" protocol.

Telnet options can be re-negotiated at any time during a Telnet session, but most options are only negotiated during the initial connection.

^ Options       ^ Request ^ Description ^
| ECHO          | WILL    | Server will provide the echo of input keys, so request the the terminal does not echo (RFC-[[rfc>857]])|
| SUP_GA        | WILL    | Server does not send or expect to receive any Telnet Go-Ahead (GA) commands (RFC-[[rfc>858]]) |
| TERM_TYPE     | DO      | Server would like the client to provide the terminal-type, if available (RFC-[[rfc>930]]) |
| TERM_SPEED    | DO      | Server would like the client to provide the terminal-speed, if available (RFC-[[rfc>1079]]) |
| SEND_LOCATION | DO      | Server would like the client to provide the user's location, if available (RFC-[[rfc>779]]) |
| NEGOTIATE_WINDOW_SIZE | DO | Server would like the client to provide the terminal dimensions (cols x rows), if available (RFC-[[rfc>1073]]) |
| NEW_ENVIRON   | DO      | Server would like the client to provide environment variables (RFC-[[rfc>1572]]) - unused |

The BINARY_TX option (disabling special treatment of CR/LF and CR/NUL) is dynamically negotiated as needed, for file transfers.

=== Debugging ===

The Terminal server logs all Telnet option negotiations using a //Debugging// log-level:

<file>
  6/20  05:56:41p  Node 1 sending telnet cmd: WILL Echo
  6/20  05:56:41p  Node 1 sending telnet cmd: WILL Suppress Go Ahead
  6/20  05:56:41p  Node 1 sending telnet cmd: DO Terminal Type
  6/20  05:56:41p  Node 1 sending telnet cmd: DO Terminal Speed
  6/20  05:56:41p  Node 1 sending telnet cmd: DO Send Location
  6/20  05:56:41p  Node 1 sending telnet cmd: DO Negotiate About Window Size
  6/20  05:56:41p  Node 1 sending telnet cmd: DO New Environment Option
  6/20  05:56:41p  Node 1 received telnet cmd: DO Echo
  6/20  05:56:41p  Node 1 received telnet cmd: DO Suppress Go Ahead
  6/20  05:56:41p  Node 1 received telnet cmd: WILL Terminal Type
  6/20  05:56:41p  Node 1 requesting telnet terminal type
  6/20  05:56:41p  Node 1 received telnet cmd: WON'T Terminal Speed
  6/20  05:56:41p  Node 1 sending telnet cmd: DON'T Terminal Speed
  6/20  05:56:41p  Node 1 received telnet cmd: WON'T Send Location
  6/20  05:56:41p  Node 1 sending telnet cmd: DON'T Send Location
  6/20  05:56:41p  Node 1 received telnet cmd: WILL Negotiate About Window Size
  6/20  05:56:41p  Node 1 received telnet sub-negotiation command: Negotiate About Window Size
  6/20  05:56:41p  Node 1 received telnet window size: 80x24
  6/20  05:56:41p  Node 1 received telnet cmd: WON'T New Environment Option
  6/20  05:56:41p  Node 1 received telnet sub-negotiation command: Terminal Type
  6/20  05:56:41p  Node 1 received telnet terminal type: ANSI
</file>


===== SSH =====
[[wp>Secure Shell]] version 2 clients are supported, by default, on the standard SSH TCP port: 22.

SSHv2 support provided by [[dev:dependencies#cryptlib]].

==== Configure ====

SSH support in the Synchronet Terminal Server can be configured via [[util:SCFG]]:Servers->Terminal Server->SSH Support:
  ╔══════════════════════════════════════════════════════╗
  ║                      SSH Support                     ║
  ╠══════════════════════════════════════════════════════╣
  ║ │Enabled                       Yes                   ║
  ║ │Interfaces                    0.0.0.0, ::           ║
  ║ │Port                          22                    ║
  ║ │Connect Timeout               10 seconds            ║
  ║ │Error Level                   Warning               ║
  ║ │User Authentication Type      Valid Key or Username ║
  ║ │File Transfer (SFTP) Support  No                    ║
  ║ │Max SFTP Inactivity           N/A                   ║
  ╚══════════════════════════════════════════════════════╝

==== cryptlib.key ====

The SSH private key is stored in the file ''[[dir:ctrl]]/cryptlib.key'' and is encrypted with the configured System Password (from [[util:SCFG]]->System). If the System Password is changed **after** the ''cryptlib.key'' file has been generated (and encrypted), you will need to delete the key file and recycle the terminal server for the key file to be regenerated and re-encrypted with the new System Password.

The following Terminal Server log message indicates a problem decrypting the ''cryptlib.key'' file:
  'Couldn't import the session key used to protect the private key' (-22) getting private key
===== RLogin =====
BSD Rlogin (RFC-[[rfc>1282]]) clients are supported, by default, on the standard RLogin TCP port: 513.

==== Configure ====
RLogin support in the Synchronet Terminal Server can be configured via [[util:SCFG]]:Servers->Terminal Server->RLogin Support:

  ╔══════════════════════════════════╗
  ║          RLogin Support          ║
  ╠══════════════════════════════════╣
  ║ │Enabled             Yes         ║
  ║ │Interfaces          0.0.0.0, :: ║
  ║ │Port                513         ║
  ╚══════════════════════════════════╝

==== History  ====

Synchronet's RLogin support has gone through some significant changes since its introduction in 2000.

=== SBBS v3.00c 2000 ===

  * [[person:digital man]] added initial support for accepting connections from BSD RLogin:
The Synchronet Telnet Server (later referred to as the "Terminal Server") was enhanced to recognize the BSD RLogin connect sequence on a secondary port (TCP port 513 by default) and bypass the "Login:" prompt if the username specified in either first (''client-user-name'') or second (''server-user-name'') strings sent from the RLogin client were recognized as a valid user/login ID (alias). The default behavior was to compare the first (''client-user-name'') string as the attempted login ID but this could be changed by checking the SBBSCTRL:Telnet->Configure->RLogin->Use 2nd Login Name checkbox. Comparing *both* RLogin-client provided strings was not supported (only one or the other would be compared against the user database).
  * The password prompt was still displayed and a valid password required in order to login as the identified user ID. If the user ID was not recognized as a valid user, then the //new user// application process was started (with the user's alias automatically filled in with the specified ''client-user-name'' or ''server-user-name'' value).

=== SBBS v3.10g 2002 ===
  * [[person:digital man]] added the ''r2'' option to [[monitor:sbbscon|sbbs]] (console) to use the second RLogin string as the username.
  * [[person:digital man]] added support for the [[module:telgate|Telnet gateway module]] to be optionally used as a gateway to an RLogin server (e.g. {{http://www.eisonline.com/|TradeWars Game Server}}, aka TWGS) - by specifying the ''TG_RLOGIN'' mode flag to the ''telnet_gate'' function (via Baja or JavaScript). The current user's login ID (alias) was sent as the ''client-user-name'' string and the user's real name was sent as the ''server-user-name'' string as part of the outbound RLogin connection establishment.

=== SBBS v3.12a 2004 ===
  * [[person:Deuce]] changed the default RLogin configuration (by this time stored in the ''Options'' field of the ''[bbs]'' section of the ''[[config:sbbs.ini]]'' file to use the **second** string sent by the RLogin client as the login ID (''USE_2ND_RLOGIN'').
  * [[person:Deuce]] changed the default configuration to enable/accept RLogin connections.
  * [[person:Deuce]] added support for automatic-login if a valid user password was supplied in either the ''client-user-name'' or ''server-user-name'' strings sent from the RLogin client (which string was assumed to be the user ID and which was assumed to be the password was determined by the "Use 2nd Login Name" option) **or** the client's IP address was listed in the (newly introduced) ''text/rlogin.can'' file, then the user would be automatically logged in without needing to provide/send a password.

=== SBBS v3.13a 2005 ===
  * [[person:Deuce]] changed the RLogin connection behavior as follows:

  if (specified user does not exist) {
      if (rlogin password recieved) {
          create new user with specified password
      }
      else {
          create new user with random password
          show password to user
          allow user to change password
          validate new password
     }
  }
  else {
      if(password is correct) {
          logon user
      }
      else {
          prompt for current password
      }
  }

=== SBBS v3.16a 2012 ===
  * [[person:echicken]] added a new mode flag (''TG_SENDPASS'') to the ''telnet_gate'' function which if combined with ''TG_RLOGIN'' mode flag would send the current user's password as the **second** RLogin string (''server-user-name'') during an outbound RLogin connection (instead of the default behavior of sending the current user's real name).

=== SBBS v3.16a 2013 ===
  * [[person:mcmlxxix]] removed echicken's ''TG_SENDPASS'' mode flag support and created a new function (''bbs.rlogin_gate'') which accepted arguments to be sent to the remote RLogin server (presumably, the user's name and password, in that order).

=== SBBS v3.16b 2014 ===

  * [[person:digital man]] removed and deprecated the ''USE_2ND_RLOGIN'' option (and related [[monitor:sbbscon|sbbs]] command-line option and [[monitor:sbbsctrl]] checkbox) as this is now the **only** behavior supported by the Synchronet [[server:Terminal]] Server: the first string received from the RLogin client (''client-user-name'') **may** be a password, the second string received (''server-user-name'') **must** be a valid user ID (alias).
  * [[person:digital man]] changed the ''bbs.rlogin_gate'' function to accept 3 optional arguments: ''client-user-name'', ''server-user-name'', and ''terminal'', in the order specified by the RFC-[[rfc>1282]].

===== JavaScript =====

Additional JavaScript objects are available to Terminal Server [[:module:|modules]] only:

  * [[http://synchro.net/docs/jsobjs.html#bbs|bbs object]]
  * [[http://synchro.net/docs/jsobjs.html#console|console object]]


====== See Also ======
  * [[:util:sexpots|Synchronet External Plain Old Telephone System Support (SEXPOTS)]]
  * [[:server:index|Servers]]

{{indexmenu_n>1}}
