RFC 4777

IBM's iSeries Telnet Enhancements

πŸ“… published November 2006, from ietf

RFC 4777 ✨ IBM's iSeries Telnet Enhancements

Okay bestie, this one is RFC 4777, called "IBM's iSeries Telnet Enhancements" πŸ’– It's by T. Murphy, Jr., P. Rieth, and J. Stevens, all from IBM, and it's dated November 2006. The category is Informational πŸŽ€ and it obsoletes RFC 2877. There's no Updates line, so it doesn't update anything.


Status of This Memo πŸ¦‹

This memo is here to give info to the Internet community 🌸 It does not specify an Internet standard of any kind, and distribution is unlimited ✨

Copyright (C) The IETF Trust (2006).

IESG Note πŸ™ˆ

This RFC is not a candidate for any level of Internet Standard. The IETF disclaims any knowledge of the fitness of this RFC for any purpose, and it's clear that the decision to publish was not based on IETF review for things like security, congestion control, or inappropriate interaction with deployed protocols 😭 The RFC Editor picked to publish this at its discretion, so readers should exercise caution when they evaluate its value for implementation and deployment. See RFC 3932 for more info 🫢

Abstract 🌈

This doc describes the interface to the Telnet server on IBM's iSeries line of midrange business computers πŸ’œ The interface lets Telnet clients ask for a Telnet terminal or printer session with specific session attributes, like device names, encryption, language support, auto-sign-on, response codes, session association, etc. ✨

The main way this works is Telnet Environment option negotiation (RFC 1572), which defines new USERVAR variables that the iSeries Telnet server will recognize 🧚

Table of Contents πŸ“‹

   1. Introduction ....................................................2
   2. Standard Telnet Option Negotiation ..............................3
   3. Enhanced Telnet Option Negotiation ..............................4
   4. Enhanced Display Emulation Support ..............................7
   5. Enhanced Display Auto-Sign-On and Password Encryption ...........9
      5.1. Data Encryption Standard (DES) Password Substitutes .......13
      5.2. Secure Hash Algorithm (SHA) Password Substitutes ..........16
   6. Kerberos Services Ticket Automatic Sign-On Support .............18
   7. Device Name Collision Processing ...............................21
   8. Enhanced Printer Emulation Support .............................22
   9. Telnet Printer Terminal Types ..................................23
   10. Startup Response Record for Printer and Display Devices .......25
      10.1. Example of a Success Response Record .....................26
      10.2. Example of an Error Response Record ......................27
      10.3. Example of a Response Record with Device Name Retry ......28
      10.4. Response Codes ...........................................31
   11. Printer Steady-State Pass-Through Interface ...................33
      11.1. Example of a Print Record ................................35
      11.2. Example of a Print Complete Record .......................37
      11.3. Example of a Null Print Record ...........................37
   12. End-to-End Print Example ......................................39
   13. Security Considerations .......................................44
   14. IANA Considerations ...........................................44
   15. Normative References ..........................................44
   16. Informative References ........................................44
   17. Relation to Other RFCs ........................................45

1. Introduction πŸŽ€

The iSeries Telnet server lets clients negotiate both terminal and printer device names through Telnet Environment Options Negotiations [RFC1572] πŸ’–

This lets Telnet servers and clients swap environment info using a set of standard or custom variables. By mixing standard VARs with custom USERVARs, the iSeries Telnet server lets a client Telnet ask for a pre-defined specific device by name πŸ¦‹

If there's no pre-defined device, the device gets created, and the client Telnet can still negotiate device attributes like the code page, character set, keyboard type, etc. ✨

Since printers can now be negotiated as a device name, there are new terminal types for requesting printers. For example, you can now negotiate "IBM-3812-1" and "IBM-5553-B01" as valid TERMINAL-TYPE options [RFC1091] πŸ–¨οΈ

Last but not least, the iSeries Telnet server lets user profile and password info get exchanged, where the password can be plain text or encrypted πŸ” If a valid combo of profile and password comes in, the client is allowed to skip the sign-on panel. For that bypass to work, the local server's QRMTSIGN system value must be either *VERIFY or *SAMEPRF πŸ‘‘

2. Standard Telnet Option Negotiation 🌸

Telnet server option negotiation [RFC855] usually starts with the server inviting the client to do terminal type negotiation (DO TERMINAL-TYPE) [RFC1091] πŸ’… The client and server then go through a series of sub-negotiations to figure out the level of terminal support they'll use. Once the terminal type is agreed, they normally negotiate a required set of extra options (EOR [RFC885], BINARY [RFC856], SGA [RFC858]) that are needed for "transparent mode" or full screen 5250/3270 block mode support ⭐ As soon as the required options are negotiated, the server stops negotiating and starts setting up the actual virtual device on the iSeries. A typical exchange might look like this:

iSeries Telnet server             Enhanced Telnet client
--------------------------        -------------------------
IAC DO TERMINAL-TYPE        -->
                            <--   IAC WILL TERMINAL-TYPE
IAC SB TERMINAL-TYPE SEND
IAC SE                      -->
                                  IAC SB TERMINAL-TYPE IS
                            <--   IBM-5555-C01 IAC SE
IAC DO EOR                  -->
                            <--   IAC WILL EOR
                            <--   IAC DO EOR
IAC WILL EOR                -->
                             .
                             .
(other negotiations)         .

Here are the actual bytes sent in that example, in hex πŸ€“

iSeries Telnet server             Enhanced Telnet client
--------------------------        -------------------------
FF FD 18                    -->
                            <--   FF FB 18
FF FA 18 01 FF F0           -->
                                  FF FA 18 00 49 42 4D 2D
                                  35 35 35 35 2D 43 30 31
                            <--   FF F0
FF FD 19                    -->
                            <--   FF FB 19
                            <--   FF FD 19
FF FB 19                    -->
                             .
                             .
(other negotiations)         .

Some negotiations are symmetrical between client and server, and some only go one direction. Also, it's allowed and totally common to bundle more than one response or request, or to combine a request with a response, so in real life the exchange might look different from what's shown above 🫢 Part 1 is done, more to come!

3. Enhanced Telnet Option Negotiation ✨

okay so, to make room for the new environment option negotiations, the server bundles an environment option invitation together with the usual terminal type invitation request πŸ’– the client then has a choice. it can send a negative acknowledgment (WONT NEW-ENVIRON), or it can start environment option sub-negotiation with the server at some point after terminal-type negotiation is done, but before the full set of negotiations required for 5250 transparent mode is finished. a client should either do one of those two things πŸŽ€ and a maximum of 1024 bytes of environment strings may be sent to the server. here's a recommended sequence, bestie πŸ¦‹

iSeries Telnet server             Enhanced Telnet client
--------------------------        -------------------------
IAC DO NEW-ENVIRON
IAC DO TERMINAL-TYPE        -->
(2 requests bundled)
                            <--   IAC WILL NEW-ENVIRON
IAC SB NEW-ENVIRON SEND
VAR IAC SE                  -->
                                  IAC SB NEW-ENVIRON IS
                                  VAR "USER" VALUE "JONES"
                                  USERVAR "DEVNAME"
                                  VALUE "MYDEVICE07"
                            <--   IAC SE
                            <--   IAC WILL TERMINAL-TYPE
                                  (do the terminal type
                                  sequence first)
IAC SB TERMINAL-TYPE SEND
IAC SE                      -->
                                  IAC SB TERMINAL-TYPE IS
                            <--   IBM-5555-C01 IAC SE
                                  (terminal type negotiations
                                  completed)
IAC DO EOR                  -->
(server will continue
with normal transparent
mode negotiations)
                            <--   IAC WILL EOR
                             .
                             .
(other negotiations)         .

Actual bytes transmitted in the above example are shown in hex below 🧚

FF FD 27
FF FD 18                    -->
(2 requests bundled)
                            <--   FF FB 27
FF FA 27 01 00 FF F0        -->
                                  FF FA 27 00 00 55 53 45
                                  52 01 4A 4F 4E 45 53 03
                                  44 45 56 4E 41 4D 45 01
                                  4D 59 44 45 56 49 43 45
                            <--   30 37 FF F0
                            <--   FF FB 18
                                  (do the terminal type
                                  sequence first)
FF FA 18 01 FF F0           -->
                                  FF FA 18 00 49 42 4D 2D
                                  35 35 35 35 2D 43 30 31
                            <--   FF F0
FF FD 19                    -->
(server will continue
with normal transparent
mode negotiations)
                            <--   FF FB 19
                             .
                             .
(other negotiations)         .

so the environment option defines 6 standard VARs: USER, JOB, ACCT, PRINTER, SYSTEMTYPE, and DISPLAY πŸ’œ the USER standard VAR holds the iSeries user profile name that gets used in auto-sign-on requests 🫢 the Telnet server makes no direct use of the other 5 VARs, and none of them are required to be sent. every standard VAR and value the server receives gets stored in a buffer, along with any USERVARs it receives (more on those below), and that buffer is made available to a registered initialization exit program, which can use it for any purpose it wants ✨

there are some good reasons you might want to send NEW-ENVIRON negotiations before TERMINAL-TYPE negotiations 😭 on an iSeries Telnet server, several virtual device modes can be negotiated: 1) VTxxx device, 2) 3270 device, and 3) 5250 device (which includes Network Station) 🌈 the mode you get depends on the TERMINAL-TYPE that was negotiated, plus any other Telnet option negotiations needed to support that mode. the iSeries Telnet server creates the desired virtual device at the first chance it thinks it has all the requested attributes it needs, and that can be as early as the end of TERMINAL-TYPE negotiations.

for Transparent mode (5250 device), the moment TERMINAL-TYPE, BINARY, and EOR options are negotiated, the Telnet server goes ahead and creates the virtual device. any NEW-ENVIRON negotiations that show up after those option negotiations are complete have no effect on device attributes, because the virtual device already exists πŸ’€

so for Transparent mode, NEW-ENVIRON negotiations are effectively closed once EOR is negotiated, since EOR is generally the last option done πŸ™ˆ

for other device modes (like VTxxx or 3270), you can't be sure when the iSeries Telnet server thinks it has all the attributes it needs to create the device πŸ’… remember, NEW-ENVIRON negotiations are optional, so the iSeries Telnet server doesn't need to wait for any NEW-ENVIRON options before creating the virtual device. it's in the clients' best interest to send NEW-ENVIRON negotiations as soon as possible, preferably before TERMINAL-TYPE is negotiated. that way, the client can be sure the requested attributes were received before the virtual device gets created πŸ‘‘


4. Enhanced Display Emulation Support ✨

okay bestie, this part is lowkey my favourite 🌸 environment option USERVARs were defined so a compliant Telnet client gets more control over the Telnet server virtual device on the iSeries, and so it can tell the Telnet server about itself πŸ’– these USERVARs let the client Telnet create or select a previously created virtual device. if the virtual device doesn't exist and has to be created, the USERVAR variables are used to create it and set its device attributes. if the virtual device already exists, its device attributes get modified πŸ¦‹

the USERVARs defined for this are:

USERVAR        VALUE              EXAMPLE         DESCRIPTION
--------       ----------------   --------------  -------------------
DEVNAME        us-ascii char(x)   MYDEVICE07      Display device name
KBDTYPE        us-ascii char(3)   USB             Keyboard type
CODEPAGE       us-ascii char(y)   437             Code page
CHARSET        us-ascii char(y)   1212            Character set
IBMSENDCONFREC us-ascii char(3)   YES | NO        Startup Response
                                                  Record desired
IBMASSOCPRT    us_ascii char(x)   RFCPRT          Printer associated
                                                  with display
                                                  device

x - up to a maximum of 10 characters
y - up to a maximum of 5 characters

for a description of the KBDTYPE, CODEPAGE, and CHARSET parameters and what values they're allowed to have, check out Chapter 8 in the Communications Configuration Reference [COMM-CONFIG], and also Appendix C in National Language Support [NLS-SUPPORT] πŸ“š

the CODEPAGE and CHARSET USERVARs must be paired with a KBDTYPE USERVAR πŸŽ€ if either CODEPAGE or CHARSET gets sent without KBDTYPE, they default to system values. you can send a default value for KBDTYPE to force the CODEPAGE and CHARSET values to be used ✨

iSeries system objects, like device names, user profiles, plain text passwords, programs, libraries, and so on, are required to be specified in English uppercase πŸ”₯ that includes:

any letter (A-Z), any number (0-9), special characters (# $ _ @)

so wherever us-ascii is specified for VAR or USERVAR values, it is recommended that uppercase ASCII values be sent 🫢 the Telnet server converts them to Extended Binary Coded Decimal Interchange Code (EBCDIC) for you 🌈

encrypted passwords are a special case (we get to them in the next section, promise πŸ™ˆ). there, both the initial password and the user profile used to build the encrypted password must be EBCDIC English uppercase, so the Telnet server can authenticate them properly πŸ’œ

the IBMASSOCPRT USERVAR gives the device name of a printer that will be associated with the display device being created πŸ–¨οΈ the printer name you give must currently exist on the Telnet server system as a device description. the IBMSENDCONFREC USERVAR is how the enhanced Telnet client tells the Telnet server that a display Startup Response Record should be sent back to the client πŸ¦‹ that record tells the client the name of the actual display device that was acquired. if the attempt doesn't work, the reason code gets set to explain why it failed πŸ’€ on top of the device name and reason code, the Startup Response Record also contains the name of the Telnet server system ✨

for more details on the Startup Response Record, see Section 11 of this document πŸ‘‘

5. Enhanced Display Auto-Sign-On and Password Encryption ✨

okay so this section is where the password stuff gets spicy πŸŒΆοΈπŸ” New IBMRSEED and IBMSUBSPW USERVARs carry the seed and substitute password info. IBMRSEED holds a random seed for both the Data Encryption Standard (DES) and Secure Hash Algorithm (SHA) password encryption, and IBMSUBSPW holds the encrypted copy of the password. the way that they team up πŸ’œ

The DES encryption uses the same 7-step DES-based password substitution scheme as APPC and Client Access. bestie, if you want the DES deep dive, go read Federal Information Processing Standards Publications (FIPS) 46-2 [FIPS-46-2] and 81 [FIPS-81] πŸ“š

The SHA encryption is described in Federal Information Processing Standards Publication 180-1 [FIPS-180-1] πŸ¦‹

The FIPS documents live at the Federal Information Processing Standards Publications link:

http://www.itl.nist.gov/fipspubs/by-num.htm

okay now the not-so-fun-but-important bit πŸ™ˆ if encrypted password exchange is not required, plain text password exchange is still allowed, using the same USERVARs you'd use for encryption. in this case the random client seed should be set either to an empty value (preferred method) or to hexadecimal zeros, which tells everyone the password is not encrypted and is plain text 🌸

⚠️ plain text password exchange is only safe-ish if the network is physically protected or a trusted network (like an intranet). if your network is vulnerable to IP address spoofing or directly connected to the Internet, you should engage in encrypted password exchange to validate a client's identity. no cap, do not skip this one πŸ’€

Additional VARs and USERVARs have also been defined so an auto-sign-on user gets more control over their startup environment, similar to what the Open Virtual Terminal (QTVOPNVT) API [SYSTEM-API] supports ✨

The standard VARs for this are:

VAR        VALUE              EXAMPLE           DESCRIPTION
--------   ----------------   ----------------  -------------------
USER       us-ascii char(x)   USERXYZ           User profile name

x - up to a maximum of 10 characters

The custom USERVARs for this are:

USERVAR       VALUE              EXAMPLE            DESCRIPTION
--------      ----------------   ----------------   -----------------
IBMRSEED      binary(8)          8-byte hex field   Random client
                                                      seed
IBMSUBSPW     binary(128)        128-byte hex field Substitute
                                                      password
IBMCURLIB     us-ascii char(x)   QGPL               Current library
IBMIMENU      us-ascii char(x)   MAIN               Initial menu
IBMPROGRAM    us-ascii char(x)   QCMD               Program to call

x - up to a maximum of 10 characters

so here's how the seed handshake goes πŸŽ€ the server asks for a USERVAR name made of a fixed part (the 8 characters "IBMRSEED") followed right away by an 8-byte hexadecimal variable part, which is the server random seed. the client makes its own 8-byte random seed and uses both seeds to encrypt the password. then the encrypted password and the client random seed both get sent to the server for authentication πŸ”

ngl this next part is where people mess up 😭 telnet environment option rules have to be followed when sending the client random seed and substituted password values. a typical environment string is a variable length hexadecimal field, so those hex fields are required to be escaped and/or byte stuffed according to RFC 854 [RFC854], because any single byte could be misread as a Telnet IAC or other Telnet option negotiation control character. the client must escape and/or byte stuff any bytes that could look like a Telnet environment option, specifically VAR, VALUE, ESC, and USERVAR 🧚

If you use the IBMSENDCONFREC USERVAR (described in Section 5 of this document) with a value of YES alongside the automatic sign-on USERVARs above, you'll get a Startup Response Record with a response code telling your Telnet client whether the auto-sign-on worked or not. see Section 11 of this document for the Startup Response Record details πŸ¦‹

here's the encrypted case, main character energy πŸ‘‘

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------------
IAC DO NEW-ENVIRON          -->
                            <--  IAC WILL NEW-ENVIRON
IAC SB NEW-ENVIRON SEND
USERVAR "IBMRSEEDxxxxxxxx"
USERVAR "IBMSUBSPW"
VAR USERVAR IAC SE          -->
                                 IAC SB NEW-ENVIRON IS
                                 VAR "USER" VALUE "DUMMYUSR"
                                 USERVAR "IBMRSEED" VALUE "yyyyyyyy"
                                 USERVAR "IBMSUBSPW" VALUE "zzzzzzzz"
                            <--  IAC SE
                             .
                             .
(other negotiations)         .

in this example, "xxxxxxxx" is an 8-byte hexadecimal random server seed, "yyyyyyyy" is an 8-byte hexadecimal random client seed, and "zzzzzzzz" is an 8-byte hexadecimal encrypted password (if DES was used) or a 20-byte hexadecimal encrypted password (if SHA was used). if the password is not valid, the sign-on panel is not bypassed. if the password is expired, the sign-on panel is not bypassed either πŸ™…β€β™€οΈ

and here are the actual bytes on the wire πŸ€“ the server seed is "7D3E488F18080404", the client seed is "4E4142334E414233", and the DES encrypted password is "DFB0402F22ABA3BA". the user profile used to make the encrypted password is "44554D4D59555352" (DUMMYUSR), with a plain text password of "44554D4D595057" (DUMMYPW).

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------
FF FD 27                    -->
                            <--  FF FB 27
FF FA 27 01 03 49 42 4D
52 53 45 45 44 7D 3E 48
8F 18 08 04 04 03 49 42
4D 53 55 42 53 50 57 03
00 FF F0                    -->
                                 FF FA 27 00 00 55 53 45
                                 52 01 44 55 4D 4D 59 55
                                 53 52 03 49 42 4D 52 53
                                 45 45 44 01 4E 41 42 33
                                 4E 41 42 33 03 49 42 4D
                                 53 55 42 53 50 57 01 DF
                                 B0 40 2F 22 AB A3 BA FF
                            <--  F0

now the plain text case 🌷

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------
IAC DO NEW-ENVIRON          -->
                            <--  IAC WILL NEW-ENVIRON
IAC SB NEW-ENVIRON SEND
USERVAR "IBMRSEEDxxxxxxxx"
USERVAR "IBMSUBSPW"
VAR USERVAR IAC SE          -->
                                 IAC SB NEW-ENVIRON IS
                                 VAR "USER" VALUE "DUMMYUSR"
                                 USERVAR "IBMRSEED" VALUE
                                 USERVAR "IBMSUBSPW" VALUE "yyyyyyyy"
                            <--  IAC SE
                             .
                             .
(other negotiations)         .

in this example, "xxxxxxxx" is an 8-byte hexadecimal random server seed, and "yyyyyyyyyy" is a 128-byte us-ascii client plain text password. if the password has expired, the sign-on panel is not bypassed πŸ’œ

and the actual bytes for this one: server seed "7D3E488F18080404", client seed empty, plain text password "44554D4D595057" (DUMMYPW), and the user profile "44554D4D59555352" (DUMMYUSR) πŸ“

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------
FF FD 27                    -->
                            <--  FF FB 27
FF FA 27 01 03 49 42 4D
52 53 45 45 44 7D 3E 48
8F 18 08 04 04 03 49 42
4D 53 55 42 53 50 57 03
00 FF F0                    -->
                                 FF FA 27 00 00 55 53 45
                                 52 01 44 55 4D 4D 59 55
                                 53 52 03 49 42 4D 52 53
                                 45 45 44 01 03 49 42 4D
                                 53 55 42 53 50 57 01 44
                            <--  55 4D 4D 59 50 57 FF F0

5.1. Data Encryption Standard (DES) Password Substitutes πŸ”βœ¨

okay so APPC and Client Access both use the well-known DES encryption algorithms to make encrypted passwords πŸ’…. A Network Station or Enhanced Client can make compatible encrypted passwords if it follows these steps. All the nitty-gritty details live in the Federal Information Processing Standards 46-2 [FIPS-46-2] πŸŽ€

1) Padded_PW 🌸

Padded_PW = Left justified user password padded to the right with '40'X to 8 bytes.

The password gets left justified in an 8-byte variable and padded on the right with '40'X until it's 8 bytes long. If it's already 8 bytes, no padding happens. For passwords of length 9 and 10, check out "Handling passwords of length 9 and 10" below. Passwords under 1 byte or over 10 bytes are not valid πŸ™…β€β™€οΈ. Also, if the password isn't in EBCDIC, convert it to EBCDIC uppercase first. Please note this one, bestie 🫢

2) XOR_PW πŸ’–

XOR_PW = Padded_PW xor '5555555555555555'X

The padded password gets XORed with 8 bytes of '55'X.

3) SHIFT_RESULT πŸ¦‹

SHIFT_RESULT = XOR_PW << 1

The whole 8-byte result gets shifted 1 bit to the left. The leftmost bit is discarded, and the rightmost bit is cleared to 0 ✨

4) PW_TOKEN πŸ‘‘

PW_TOKEN = DES_ECB_mode(SHIFT_RESULT,              /* key  */
                        userID_in_EBCDIC_uppercase /* data */ )

This shifted result becomes the key for the Data Encryption Standard (Federal Information Processing Standards 46-2 [FIPS-46-2]) to encipher the user identifier. If the user identifier is less than 8 bytes, it's left justified in an 8-byte variable and padded to the right with '40'X. If the user identifier is 9 or 10 bytes, it first gets padded to the right with '40'X up to 10 bytes. Then bytes 9 and 10 get "folded" into bytes 1-8 using this algorithm:

Bit 0 is the high-order bit (i.e., has value of '80'X).

Byte 1, bits 0 and 1 are replaced with byte 1, bits 0 and 1
Exclusive OR'ed with byte 9, bits 0 and 1.
Byte 2, bits 0 and 1 are replaced with byte 2, bits 0 and 1
Exclusive OR'ed with byte 9, bits 2 and 3.
Byte 3, bits 0 and 1 are replaced with byte 3, bits 0 and 1
Exclusive OR'ed with byte 9, bits 4 and 5.
Byte 4, bits 0 and 1 are replaced with byte 4, bits 0 and 1
Exclusive OR'ed with byte 9, bits 6 and 7.
Byte 5, bits 0 and 1 are replaced with byte 5, bits 0 and 1
Exclusive OR'ed with byte 10, bits 0 and 1.
Byte 6, bits 0 and 1 are replaced with byte 6, bits 0 and 1
Exclusive OR'ed with byte 10, bits 2 and 3.
Byte 7, bits 0 and 1 are replaced with byte 7, bits 0 and 1
Exclusive OR'ed with byte 10, bits 4 and 5.
Byte 8, bits 0 and 1 are replaced with byte 8, bits 0 and 1
Exclusive OR'ed with byte 10, bits 6 and 7.

User identifiers greater than 10 bytes or less than 1 byte are not the result of this encryption 🚫. This is the ID known as PW_TOKEN in the paper.

5) Increment PWSEQs and store it πŸ”’

Each LU has to keep a pair of sequence numbers for ATTACHs sent and received on each session. Every time an ATTACH is generated (and password substitutes are in use on the session), the sending sequence number, PWSEQs, goes up by one and gets saved for next time. Both values are set to zero at BIND time, so the first use of PWSEQs is 1 and it goes up by one with each use. A new field gets added to the ATTACH to carry this sequence number.

Here's the twist: in certain error conditions, the sending side can increment the sequence number while the receiver doesn't. When the sender sends a later ATTACH, the receiver will notice a missing sequence. That's allowed πŸ™Œ But the sequence number received must always be larger than the previous one, even if some are missing.

The maximum number of consecutive missing sequence numbers allowed is 16. If that gets exceeded, the session is unbound with a protocol violation πŸ’€

Note: the sequence number must be incremented for every ATTACH sent. The sequence number field is only required to be included in the FMH5 if a password substitute is sent (byte 4, bit 3 on). πŸ’œ

6) RDrSEQ 🧚

RDrSEQ = RDr + PWSEQs  /* RDr is server seed. */

The current value of PWSEQs gets added to RDr, which is the random value received from the partner LU on this session. That gives you RDrSEQ, basically a predictably modified version of the random value the partner LU sent at BIND time πŸ¦‹

7) PW_SUB 🌈

PW_SUB = DES_CBC_mode(PW_TOKEN,        /* key      */
                      (RDrSEQ,         /* 8 bytes  */
                       RDs,            /* 8 bytes  */
                       ID xor RDrSEQ,  /* 16 bytes */
                       PWSEQs,         /* 8 bytes  */
                       )               /* data     */
                      )

PW_TOKEN is used as the key for the DES function to generate an 8-byte value from the following inputs. The DES CBC mode Initialization Vector (IV) is 8 bytes of '00'X πŸŽ€

  • RDrSEQ: the random data value received from the partner LU, plus the sequence number.
  • RDs: the random data value sent to the partner LU on BIND for this session.
  • A 16-byte value, created by padding the user identifier with '40'X to a length of 16 bytes, then XORing the two 8-byte halves of the padded user identifier with the RDrSEQ value.
    • Note: the User ID must first be converted to EBCDIC uppercase πŸ’…
  • PWSEQs: the sequence number.

This is pretty similar to what happens during LU-LU verification in the Enhanced LU-LU Bind Security. The enciphered random data that comes out is the 'password substitute' πŸ”

8) Handling passwords of length 9 and 10 🧩

  1. Generate PW_TOKENa by using characters 1 to 8 of the password, plus steps 1-4 from the previous section.
  2. Generate PW_TOKENb by using characters 9 and 10, plus steps 1-4 from the previous section. In this case, the Padded_PW from step 1 will be characters 9 and 10 padded to the right with '40'X, for a total length of 8.
  3. Compute PW_TOKEN = PW_TOKENa xor PW_TOKENb.
  4. Now compute PW_SUB by performing steps 5-7 from the previous section.

9) Example DES Password Substitute Calculation πŸ“

ID:           USER123
Password:     ABCDEFG
Server seed:  '7D4C2319F28004B2'X
Client seed:  '08BEF662D851F4B1'X
PWSEQs:       1     (PWSEQs is a sequence number needed in the
                     7-step encryption, and it is always one)

DES Encrypted Password should be: '5A58BD50E4DD9B5F'X

5.2. Secure Hash Algorithm (SHA) Password Substitutes πŸ”’πŸ’«

A Network Station or Enhanced Client can generate SHA encrypted passwords if it follows these steps πŸŽ€

1) Convert the user identifier to uppercase UNICODE format (if it's not already in this format) 🌷

The user identifier must be left justified in a 10-byte variable and padded to the right with '40'X up to 10 bytes before it gets converted to UNICODE. If the user's password is 10 bytes in length, no padding will occur. User identifiers under 1 byte or over 10 bytes are not valid πŸ™…β€β™€οΈ After conversion to UNICODE, the user identifier is 20 bytes long, so the variable that holds the UNICODE user identifier should be 20 bytes long too.

2) Ensure the password is in UNICODE format (if it's not already in this format) πŸ¦‹

The user's password must be left justified in a 128-byte variable. It doesn't need to be padded to the right with '40'X up to 128 bytes. Passwords under 1 byte or over 128 bytes are not valid. After conversion to UNICODE, the password is 2 times its original length, so the maximum length of the variable that holds the UNICODE password is 256 bytes 🌈

3) Create a 20-byte password token as follows πŸ’–

PW_token = SHA-1(uppercase_unicode_userid,         /* 20 bytes */
                 unicode_password)      /* from 2 to 256 bytes */

The actual routine for the SHA-1 processing depends on the programming language you're using. For example, if you're using Java, use the java.security class to do the SHA-1 processing πŸ’… The PW_token gets used in a later step to actually generate the final substitute password ✨

4) Increment PWSEQs and store it πŸ”’

5) Create the 20-byte substitute password as follows πŸ‘‘

PW_SUB = SHA-1(PW_token,                        /* 20 bytes */
               serverseed,                      /*  8 bytes */
               clientseed,                      /*  8 bytes */
               uppercase_unicode_userid,        /* 20 bytes */
               PWSEQ)                           /*  8 bytes */

Same deal as before: the actual SHA-1 routine depends on the programming language being used. For example, if using Java, use the java.security class to perform the actual SHA-1 processing 🫢

6) Example SHA Password Substitute Calculation πŸ“

ID:           USER123
Password:     AbCdEfGh123?+
Server seed:  '3E3A71C78795E5F5'X
Client seed:  'B1C806D5D377D994'X
PWSEQs:       1     (PWSEQs is a sequence number needed in the
                     SHA encryption, and it is always one)

SHA Encrypted Password should be:

         'E7FAB5F034BEDA42E91F439DD07532A24140E3DD'X

6. Kerberos Services Ticket Automatic Sign-On Support ✨

okay bestie, this section is about letting the sign-on panel get skipped using a Kerberos ticket 🎟️ 🫢 An iSeries Telnet server specific USERVAR holds the whole GSS token for use on the iSeries πŸ’… Enhanced Telnet clients have to get the Kerberos services ticket from a Key Distribution Center (KDC) πŸ”‘ The only implementation steps given for getting that ticket are the Microsoft SSPI example further down, so that's the one we're looking at πŸ‘€ If you want more on Kerberos services tickets, check your Network Authentication Service (NAS) documentation πŸ“š

The custom USERVAR defined here is:

USERVAR   VALUE         EXAMPLE              DESCRIPTION
--------- ------------- -------------------- -------------------
IBMTICKET binary(16384) 16384-byte hex field Kerberos services token

Several other USERVARs from Section 6 can team up with IBMTICKET so the user gets more control over their startup environment πŸŽ€

The custom USERVARs for that are:

USERVAR       VALUE              EXAMPLE            DESCRIPTION
--------      ----------------   ----------------   -----------------
IBMCURLIB     us-ascii char(x)   QGPL               Current library
IBMIMENU      us-ascii char(x)   MAIN               Initial menu
IBMPROGRAM    us-ascii char(x)   QCMD               Program to call

x - up to a maximum of 10 characters

If you use IBMSENDCONFREC from Section 5 with a value of YES alongside the Kerberos ticket USERVARs, you'll get a Startup Response Record back 🧾 That record has a response code that tells your Telnet client whether the Kerberos validation worked or didn't πŸ™ˆ See Section 11 for the full scoop on the Startup Response Record ✨

Here's the Microsoft SSPI example showing how to grab the client security token, which holds the Kerberos services ticket πŸ¦‹

  1. Get a handle to the user's credentials:
PSecurityFunctionTable pSSPI_;
CredHandle credHandle;
TimeStamp  timeStamp;

ss = pSSPI_->AcquireCredentialsHandle(
             NULL,                 // Principal
             "Kerberos",           // PackageName
             SECPKG_CRED_OUTBOUND, // CredentialUse
             NULL,                 // LogonID
             NULL,                 // AuthData
             NULL,                 // GetKeyFnc
             NULL,                 // GetKeyArg
             &credHandle,          // CredHandle
             &timeStamp);          // ExpireTime
  1. Set up the security context to "request delegation" 🫢 Mutual authentication gets requested too, but it's not required and may not actually happen, so don't count on it πŸ™ƒ
CtxtHandle newContext;
unsigned long contextAttr;
unsigned char token[16384] ;
unsigned long tokenLen = sizeof(token);
SecBuffer sbo = {tokenLen, SECBUFFER_TOKEN, token};
SecBufferDesc sbdo = {SECBUFFER_VERSION, 1, &sbo}

pSSPI_->InitializeSecurityContext(
        &credHandle,               // CredHandle
        NULL,                      // Context
        "krbsrv400/fullyqualifiedLowerCaseSystemName",
                                   // ServicePrincipalName
        ISC_REQ_CONNECTION|ISC_REQ_DELEGATE|ISC_REQ_MUTUAL_AUTH,
                                   // ContextRequest
        NULL,                      // Reserved
        SECURITY_NATIVE_DREP,      // DataRep
        NULL,                      // Input
        NULL,                      // Reserved
        &newContext,               // NewContext
        &sbdo,                     // Output
        &contextAttr,              // ContextAttr
        &timeStamp);               // ExpireTime
  1. Free the user credentials handle with FreeCredentialsHandle() 🧹
  2. Send the security token to the Telnet Server, padded with escape characters πŸ’–

Here's how the Kerberos Token Negotiation goes down πŸ‘€

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------------
IAC DO NEW-ENVIRON          -->
                            <--  IAC WILL NEW-ENVIRON
IAC SB NEW-ENVIRON SEND
USERVAR "IBMRSEEDxxxxxxxx"
VAR USERVAR IAC SE          -->
                                 IAC SB NEW-ENVIRON IS
                                 USERVAR "IBMTICKET" VALUE
                                 "zzzzzzzz..."
                            <--  IAC SE
                             .
                             .
(other negotiations)         .

So in that example, "xxxxxxxx" is an 8-byte hexadecimal random server seed, and "zzzzzzzz..." is the whole Kerberos services token πŸŽ€ If the token isn't valid, the sign-on panel is not bypassed, so the user still has to type stuff in 😭 Also, the Kerberos token doesn't need a random server seed, even though the Telnet Server sends one anyway πŸ€·β€β™€οΈ

Now the actual bytes, in hex 🧚 The server seed here is "7D3E488F18080404", and the Kerberos services token starts with "DFB0402F22ABA3BA...". The full token isn't shown, because it could be 16384 bytes and the document would be absolutely massive πŸ“ As Section 6 describes, the client has to escape and/or byte stuff any Kerberos token bytes. Those bytes could be seen as a Telnet environment option [RFC1572], specifically VAR, VALUE, ESC, and USERVAR πŸ¦‹

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------
FF FD 27                    -->
                            <--  FF FB 27
FF FA 27 01 03 49 42 4D
52 53 45 45 44 7D 3E 48
8F 18 08 04 04 00 03 FF
F0                          -->
                                 FF FA 27 00 03 49 42 4D
                                 54 49 43 48 45 54 01 DF
                                 B0 40 2F 22 AB A3 BA...
                            <--  FF F0

7. Device Name Collision Processing πŸ’…

Okay so device name collision is when a Telnet client sends the server a virtual device name it wants, but that device is already being used on the server 😬 When that happens, the Telnet server asks the client to try a different device name πŸ”„ The environment option negotiation uses the DEVNAME USERVAR to pass along the virtual device name ✨ Here's how the Telnet server asks the client for a new DEVNAME when there's a collision πŸ‘‘

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------
IAC SB NEW-ENVIRON SEND
VAR USERVAR IAC SE         -->

Server requests all environment variables be sent.

                                 IAC SB NEW-ENVIRON IS USERVAR
                                 "DEVNAME" VALUE "MYDEVICE1"
                                 USERVAR "xxxxx" VALUE "xxx"
                                 ...
                           <--   IAC SE

Client sends all environment variables, including DEVNAME.  Server
tries to select device MYDEVICE1.  If the device is already in use,
server requests DEVNAME be sent again.

IAC SB NEW-ENVIRON SEND
USERVAR "DEVNAME" IAC SE   -->

Server sends a request for a single environment variable: DEVNAME

                                 IAC SB NEW-ENVIRON IS USERVAR
                           <--   "DEVNAME" VALUE "MYDEVICE2" IAC SE

Client sends one environment variable, calculating a new value of
MYDEVICE2.  If MYDEVICE2 is different from the last request, then
server tries to select device MYDEVICE2, else server disconnects
client.  If MYDEVICE2 is also in use, server will send DEVNAME
request again and keep doing so until it receives a device that is
not in use, or the same device name twice in row.

Basically, if the device is busy, the server keeps asking for DEVNAME again πŸ” It only stops once it gets a device that isn't in use, or if the same device name shows up twice in a row, which is when the server disconnects the client πŸ’€


8. Enhanced Printer Emulation Support πŸ–¨οΈπŸŒΈ

Telnet environment option USERVARs have been defined to give a compliant Telnet client more say over the Telnet server virtual device on the iSeries πŸ’– These USERVARs let the client pick a virtual device that already exists, or auto-create a new one with the attributes it asked for 🧚

The enhancements are open to any Telnet client that decides to support the new negotiations, so it's giving "everyone's invited" energy 🫢

The USERVARs defined for this are:

USERVAR       VALUE            EXAMPLE           DESCRIPTION
------------- ---------------- ----------------  -------------------
DEVNAME       us-ascii char(x) PRINTER1          Printer device name
IBMIGCFEAT    us-ascii char(6) 2424J0            IGC feature (DBCS)
IBMMSGQNAME   us-ascii char(x) QSYSOPR           *MSGQ name
IBMMSGQLIB    us-ascii char(x) QSYS              *MSGQ library
IBMFONT       us-ascii char(x) 12                Font
IBMFORMFEED   us-ascii char(1) C | U | A         Formfeed
IBMTRANSFORM  us-ascii char(1) 1 | 0             Transform
IBMMFRTYPMDL  us-ascii char(x) *IBM42023         Mfg. type and model
IBMPPRSRC1    binary(1)        1-byte hex field  Paper source 1
IBMPPRSRC2    binary(1)        1-byte hex field  Paper source 2
IBMENVELOPE   binary(1)        1-byte hex field  Envelope hopper
IBMASCII899   us-ascii char(1) 1 | 0             ASCII 899 support
IBMWSCSTNAME  us-ascii char(x) *NONE             WSCST name
IBMWSCSTLIB   us-ascii char(x) *LIBL             WSCST library

x - up to a maximum of 10 characters

The "IBM" prefix marks the iSeries-specific attributes πŸ“ DEVNAME is used for both displays and printers πŸ–¨οΈ IBMFONT and IBMASCII899 are only used in SBCS environments 🌈

For most of these parameters (just drop the "IBM" from the USERVAR name) and what values they're allowed to take, check Chapter 8 in the Communications Configuration Reference [COMM-CONFIG] πŸ“š

IBMIGCFEAT supports these variable DBCS language identifiers in position 5. Positions 1-4 have to be '2424', and position 6 has to be '0' πŸŽ€

    'J' = Japanese              'K' = Korean
    'C' = Traditional Chinese   'S' = Simplified Chinese

IBMTRANSFORM and IBMASCII899 values map like this πŸ’œ

    '1' = Yes  '0' = No

IBMFORMFEED values map like this ✨

    'C' = Continuous  'U' = Cut  'A' = Autocut

Now, IBMPPRSRC1, IBMPPRSRC2, and IBMENVELOPE are custom USERVARs that don't line up directly with their descriptions in Chapter 8 of the Communications Configuration Reference [COMM-CONFIG] 😭 To map them, use the index below 🧚

IBMPPRSRC1    HEX     IBMPPRSRC2    HEX     IBMENVELOPE    HEX
----------   -----    ----------   -----    -----------   -----
*NONE        'FF'X    *NONE        'FF'X    *NONE         'FF'X
*MFRTYPMDL   '00'X    *MFRTYPMDL   '00'X    *MFRTYPMDL    '00'X
*LETTER      '01'X    *LETTER      '01'X    *B5           '06'X
*LEGAL       '02'X    *LEGAL       '02'X    *MONARCH      '09'X
*EXECUTIVE   '03'X    *EXECUTIVE   '03'X    *NUMBER9      '0A'X
*A4          '04'X    *A4          '04'X    *NUMBER10     '0B'X
*A5          '05'X    *A5          '05'X    *C5           '0C'X
*B5          '06'X    *B5          '06'X    *DL           '0D'X
*CONT80      '07'X    *CONT80      '07'X
*CONT132     '08'X    *CONT132     '08'X
*A3          '0E'X    *A3          '0E'X
*B4          '0F'X    *B4          '0F'X
*LEDGER      '10'X    *LEDGER      '10'X

9. Telnet Printer Terminal Types ✨

okay bestie, printer pass-through mode gets its very own set of new Telnet options πŸ–¨οΈπŸ’– To turn it on, the client and server must agree to support at least the Transmit-Binary, End-Of-Record, and Terminal-Type Telnet options. The new printer terminal types are:

TERMINAL-TYPE  DESCRIPTION
-------------  -------------------
IBM-5553-B01   Double-Byte printer
IBM-3812-1     Single-Byte printer

The specific characteristics of the IBM-5553-B01 or IBM-3812-1 printers are set through the USERVAR IBMMFRTYPMDL, which specifies the manufacturer type and model. πŸŽ€

Here's a typical negotiation to get printer pass-through mode going. In this example, the server kicks things off by sending the DO TERMINAL-TYPE request. πŸ¦‹

Quick DBCS note 🫢: if IBMTRANSFORM is set to 1 (use Host Print Transform), the virtual device created is a 3812, not a 5553. So IBM-3812-1 (and not IBM-5553-B01) should be negotiated for TERMINAL-TYPE.

iSeries Telnet server           Enhanced Telnet client
--------------------------      --------------------------
IAC DO NEW-ENVIRON         -->
                              <--  IAC WILL NEW-ENVIRON
IAC SB NEW-ENVIRON SEND
VAR USERVAR IAC SE         -->
                                   IAC SB NEW-ENVIRON IS
                                   USERVAR "DEVNAME" VALUE "PCPRINTER"
                                   USERVAR "IBMMSGQNAME" VALUE "QSYSOPR"
                                   USERVAR "IBMMSGQLIB" VALUE "*LIBL"
                                   USERVAR "IBMTRANSFORM" VALUE "0"
                                   USERVAR "IBMFONT" VALUE "12"
                                   USERVAR "IBMFORMFEED" VALUE "C"
                                   USERVAR "IBMPPRSRC1" VALUE ESC '01'X
                                   USERVAR "IBMPPRSRC2" VALUE '04'X
                                   USERVAR "IBMENVELOPE" VALUE IAC 'FF'X

                              <--  IAC SE
IAC DO TERMINAL-TYPE       -->
                              <--  IAC WILL TERMINAL-TYPE
IAC SB TERMINAL-TYPE SEND

IAC SE                     -->
                                   IAC SB TERMINAL-TYPE IS IBM-3812-1
                              <--  IAC SE
IAC DO BINARY              -->
                              <--  IAC WILL BINARY
IAC DO EOR                 -->
                              <--  IAC WILL EOR

A few things to spot in that example πŸ‘€βœ¨ The IBMPPRSRC1 value needs escaping with ESC, following the Telnet environment options [RFC1572]. The IBMPPRSRC2 value doesn't need an ESC because '04'X doesn't clash with environment options. And to send 'FF'X as the IBMENVELOPE value, you escape it by using another 'FF'X (called "doubling") so it doesn't get read as a Telnet character, per the Telnet protocol specification [RFC854]. Slay the details πŸ’…

Here are the actual bytes from the same example, in hex πŸ€“

iSeries Telnet server            Enhanced Telnet client
--------------------------       --------------------------
FF FD 27                    -->
                            <--  FF FB 27
FF FA 27 01 00 03 FF F0     -->
                                 FF FA 27 00 03 44 45 56
                                 4E 41 4D 45 01 50 43 50
                                 52 49 4E 54 45 52 03 49
                                 42 4D 4D 53 47 51 4E 41
                                 4D 45 01 51 53 59 53 4F
                                 50 52 03 49 42 4D 4D 53
                                 47 51 4C 49 42 01 2A 4C
                                 49 42 4C 03 49 42 4D 54
                                 52 41 4E 53 46 4F 52 4D
                                 01 30 03 49 42 4D 46 4F
                                 4E 54 01 31 32 03 49 42
                                 4D 46 4F 52 4D 46 45 45
                                 44 01 43 03 49 42 4D 50
                                 50 52 53 52 43 31 01 02
                                 01 03 49 42 4D 50 50 52
                                 53 52 43 32 01 04 03 49
                                 42 4D 45 4E 56 45 4C 4F
                            <--  50 45 01 FF FF FF F0
FF FD 18                    -->
                            <--  FF FB 18
FF FA 18 01 FF F0           -->
                                 FF FA 18 00 49 42 4D 2D
                            <--  33 38 31 32 2D 31 FF F0
FF FD 00                    -->
                            <--  FF FB 00
FF FD 19                    -->
                                 FF FB 19

10. Startup Response Record for Printer and Display Devices 🧚

Once Telnet negotiation for a 5250 pass-through mode wraps up, the iSeries Telnet server starts a virtual device power-on sequence (printer or display) on behalf of the Telnet client πŸ’« It then sends the client a Startup Response Record with the status of that power-on sequence, showing whether it worked or failed.

Below are two example Startup Response Records. The source device is a type 3812 model 01 printer named "PCPRINTER" on the target system "TARGET". Figure 1 is a successful response, and Figure 2 is an error response. 🌸

10.1. Example of a Success Response Record

The response record in Figure 1 was sent by an iSeries at Release V4R2. It's a good example of the target sending back a successful Startup Response Record πŸŽ‰

+------------------------------------------------------------------+
|       +-----  Pass-Through header                                |
|       |          +---  Response data                             |
|       |          |            +----  Start diagnostic information|
|       |          |            |                                  |
| +----------++----------++--------------------------------------- |
| |          ||          ||                                        |
| 004912A090000560060020C0003D0000C9F9F0F2E3C1D9C7C5E34040D7C3D7D9 |
|                                 |      | T A R G E T     P C P R |
|                                 +------+                         |
|                           Response Code (I902)                   |
|                                                                  |
| ---------------------------------------------------------------- |
|                                                                  |
| C9D5E3C5D9400000000000000000000000000000000000000000000000000000 |
|  I N T E R                                                       |
|                                                                  |
|                  +------- End of diagnostic information          |
|                  |                                               |
| -----------------+                                               |
|                  |                                               |
| 000000000000000000                                               |
+------------------------------------------------------------------+

Figure 1. Example of a success response record

  • '0049'X = Length pass-through data, including this length field
  • '12A0'X = GDS LU6.2 header
  • '90000560060020C0003D0000'X = Fixed value fields
  • 'C9F9F0F2'X = Response Code (I902)
  • 'E3C1D9C7C5E34040'X = System Name (TARGET)
  • 'D7C3D7D9C9D5E3C5D940'X = Object Name (PCPRINTER)

10.2. Example of an Error Response Record

The response record in Figure 2 reports an error 😬 The virtual device named "PCPRINTER" isn't available on the target system "TARGET" because the device is not available. You'd normally see this error if the printer were already assigned to another Telnet session. Oof, relatable πŸ’€

+------------------------------------------------------------------+
|       +-----  Pass-Through header                                |
|       |          +---  Response data                             |
|       |          |            +----  Start diagnostic information|
|       |          |            |                                  |
| +----------++----------++--------------------------------------- |
| |          ||          ||                                        |
| 004912A09000056006008200003D0000F8F9F0F2E3C1D9C7C5E34040D7C3D7D9 |
|                                 |      | T A R G E T     P C P R |
|                                 +------+                         |
|                           Response Code (8902)                   |
|                                                                  |
| ---------------------------------------------------------------- |
|                                                                  |
| C9D5E3C5D9400000000000000000000000000000000000000000000000000000 |
|  I N T E R                                                       |
|                                                                  |
|                  +------- End of diagnostic information          |
|                  |                                               |
| -----------------+                                               |
|                  |                                               |
| 000000000000000000                                               |
+------------------------------------------------------------------+

Figure 2. Example of an error response record

  • '0049'X = Length pass-through data, including this length field
  • '12A0'X = GDS LU6.2 header
  • '90000560060020C0003D0000'X = Fixed value fields
  • 'F8F9F0F2'X = Response Code (8902)
  • 'E3C1D9C7C5E34040'X = System Name (TARGET)
  • 'D7C3D7D9C9D5E3C5D940'X = Object Name (PCPRINTER)

10.3. Example of a Response Record with Device Name Retry ✨

okay so the Response Record can team up with the DEVNAME Environment variable πŸŽ€ to let client emulators tell users when a connection fails πŸ’…. ngl this combo is iconic for emulators that accept multiple device names to try on session connections πŸ¦‹. the client can walk through a list of possible device names and give feedback based on the response code(s) it gets for each device name that got rejected 🫢.

this next sequence shows a negotiation between the client and the server where the client requests a named device "RFCTEST" 🌸. that device name is already assigned to an existing condition 😭. the server responds with a Response Record showing an 8902 response code πŸ’€, so the client can tell the user that the device name they just tried is already in use πŸ™ˆ. after the Response Record, the server invites the client to try another device name πŸ’–. because the client used the same device name again, the server closed the session πŸ”₯.

iSeries Telnet server            Enhanced Telnet client
--------------------------       -------------------------
IAC DO NEW-ENVIRON          -->
                            <--   IAC WILL NEW-ENVIRON
IAC DO TERMINAL-TYPE        -->
                            <--   IAC WILL TERMINAL-TYPE
IAC SB NEW-ENVIRON SEND
USERVAR "IBMRSEEDxxxxxxxx"
VAR USERVAR IAC SE          -->
                                  IAC SB NEW-ENVIRON IS
                                  USERVAR "DEVNAME"
                                  VALUE "RFCTEST"
                                  USERVAR "IBMSENDCONFREC"
                                  VALUE "YES"
                            <--   IAC SE
IAC SB TERMINAL-TYPE SEND
IAC SE                      -->
                                  IAC SB TERMINAL-TYPE IS
                            <--   IBM-3180-2 IAC SE
                                  (terminal type negotiations
                                  completed)
IAC DO EOR                  -->
                            <--   IAC WILL EOR
IAC WILL EOR                -->
                            <--   IAC DO EOR
IAC DO BINARY               -->
                            <--   IAC WILL BINARY
IAC WILL BINARY             -->
                            <--   IAC DO BINARY
(73 BYTE RFC 1205 RECORD
WITH 8902 ERROR CODE)       -->
IAC SB NEW-ENVIRON SEND
USERVAR "DEVNAME"
IAC SE                      -->
                                  IAC SB NEW-ENVIRON IS
                                  USERVAR "DEVNAME"
                                  VALUE "RFCTEST"
                                  USERVAR "IBMSENDCONFREC"
                                  VALUE "YES"
                            <--   IAC SE
(server closes connection)

and here are the actual bytes sent in the example above, shown in hex 🧚

iSeries Telnet server            Enhanced Telnet client
--------------------------       --------------------------
FF FD 27                    -->
                            <--  FF FB 27
FF FD 18                    -->
                            <--  FF FB 18
FF FA 27 01 03 49 42 4D
52 53 45 45 44 C4 96 67
76 9A 23 E3 34 00 03 FF
F0                          -->
                                 FF FA 27 00 03 44 45 56
                                 4E 41 4D 45 01 52 46 43
                                 54 45 53 54 03 49 42 4D
                                 53 45 4E 44 43 4F 4E 46
                                 52 45 43 01 59 45 53 FF
                            <--  F0
FF FA 18 01 FF F0           -->
                            <--  FF FA 18 00 49 42 4D 2D
                                 33 31 38 30 2D 32 FF F0
FF FD 19                    -->
                            <--  FF FB 19
FF FB 19                    -->
                            <--  FF FD 19
FF FD 00                    -->
                            <--  FF FB 00
FF FB 00                    -->
                            <--  FF FD 00
00 49 12 A0 90 00 05 60
06 00 20 C0 00 3D 00 00
F8 F9 F0 F2 D9 E2 F0 F3
F5 40 40 40 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 FF EF                    -->
FF FA 27 01 03 44 45 56
4E 41 4D 45 FF F0          -->
                            <--  FF FA 27 00 03 44 45 56
                                 4E 41 4D 45 01 52 46 43
                                 54 45 53 54 03 49 42 4D
                                 53 45 4E 44 43 4F 4E 46
                                 52 45 43 01 59 45 53 FF
                                 F0

10.4. Response Codes πŸ’…

here's the lineup of Start-Up Response Record success response codes πŸ’œ

CODE    DESCRIPTION
----    ------------------------------------------------------
I901    Virtual device has less function than source device.
I902    Session successfully started.
I906    Automatic sign-on requested, but not allowed.
        Session still allowed; a sign-on screen will be
        coming.

and now the error response codes for the Start-Up Response Record πŸ™ˆ

CODE    DESCRIPTION
----    ------------------------------------------------------
2702    Device description not found.
2703    Controller description not found.
2777    Damaged device description.
8901    Device not varied on.
8902    Device not available.
8903    Device not valid for session.
8906    Session initiation failed.
8907    Session failure.
8910    Controller not valid for session.
8916    No matching device found.
8917    Not authorized to object.
8918    Job canceled.
8920    Object partially damaged.
8921    Communications error.
8922    Negative response received.
8923    Start-up record built incorrectly.
8925    Creation of device failed.
8928    Change of device failed.
8929    Vary on or vary off failed.
8930    Message queue does not exist.
8934    Start-up for S/36 WSF received.
8935    Session rejected.
8936    Security failure on session attempt.
8937    Automatic sign-on rejected.
8940    Automatic configuration failed or not allowed.
I904    Source system at incompatible release.

these are the error codes for non-Kerberos Services Token automatic sign-on 🌈

   CODE    DESCRIPTION
   ----    ------------------------------------------------------
   0001    System error.
   0002    Userid unknown.
   0003    Userid disabled.
   0004    Invalid password/passphrase/token.
   0005    Password/passphrase/token is expired.
   0006    Pre-V2R2 password.
   0008    Next invalid password/passphrase/token will revoke userid.

and last but definitely not least, the error codes for Kerberos Services Token automatic sign-on support πŸ¦‹

CODE    DESCRIPTION
----    ------------------------------------------------------
0001    User profile is disabled.
0002    Kerberos principal maps to a system user profile.
0003    Enterprise Identity Map (EIM) configuration error.
0004    EIM does not map Kerberos principal to user profile.
0005    EIM maps Kerberos principal to multiple user profiles.
0006    EIM maps Kerberos principal to user profile not found on
        system.
1000    None of the requested mechanisms are supported by the
        local system.
2000    The input name is not formatted properly or is not valid.
6000    The received input token contains an incorrect signature.
7000    No credentials available or credentials valid for context
        init only.
9000    Consistency checks performed on the input token failed.
A000    Consistency checks on the cred structure failed.
B000    Credentials are no longer valid.
D000    The runtime failed for reasons that are not defined at the
        GSS level.

okay this part is SO important πŸ‘‘ when USERVAR DEVNAME, USERVAR IBMSENDCONFREC, USERVAR IBMSUBSPW, and USERVAR IBMRSEED are all used together, device errors take precedence over automatic sign-on errors πŸ”₯. here's how it plays out:

  1. if the requested named device is not available, or an error happens while the server is trying to create the device, a device related return code (like 8902) gets sent to the client system in the display confirmation record πŸ’€.
  2. if the requested named device is available, or no errors happen while creating the device on the server system, an automatic sign-on return code (like 0002) gets sent to the client system in the display confirmation record 🌸.

11. Printer Steady-State Pass-Through Interface πŸ’–

okay so this part is for after the startup confirmation records are all done ✨ once that handshake wraps up, the pass-through session is officially live and everything below applies πŸ¦‹

Here's the printer header interface that Telnet uses πŸŽ€

+------------------------------------------------------------------+
|   +-- Length of structure (LLLL)                                 |
|   |                                                              |
|   |    +-- GDS identifier                                        |
|   |    |                                                         |
|   |    |    +-- Data flow record                                 |
|   |    |    |                                                    |
|   |    |    |   +-- Length of pass-through specific header (LL)  |
|   |    |    |   |                                                |
|   |    |    |   |   +-- Flags                                    |
|   |    |    |   |   |                                            |
|   |    |    |   |   |   +-- Printer operation code               |
|   |    |    |   |   |   |                                        |
|   |    |    |   |   |   |      +-- Diagnostic field - zero pad to|
|   |    |    |   |   |   |      |   LL specified                  |
|   |    |    |   |   |   |      |                                 |
|   |    |    |   |   |   |      |            +-- Printer data     |
|   |    |    |   |   |   |      |            |                    |
| +--+ +--+ +--+ ++ +--+ ++ +----------+ +----------------+        |
| |  | |  | |  | || |  | || |          | |                |        |
| xxxx 12A0 xxxx xx xxxx xx xxxxxxxxxxxx ... print data ...        |
|                                                                  |
+------------------------------------------------------------------+

        Figure 3.  Layout of the printer pass-through header

okay the byte breakdown is where it gets spicy 🌢️ here's the lineup:

  • Bytes 0-1: the length of the whole structure, this field included (LLLL) πŸ“
  • Bytes 2-3: the GDS identifier, which is '12A0'X πŸ†”
  • Bytes 4-5: the data flow record 🌊 this field holds flags that tell you what kind of data pass-through should expect to find right after this header. bits 0-2 in the first byte are basically exclusives, so if one of them is set to '1'B, the rest are '0'B. here's what every bit means:
BIT       DESCRIPTION

0         Start-Up confirmation
1         Termination record
2         Start-Up Record
3         Diagnostic information included
4 - 5     Reserved
6         Reserved
7         Printer record
8 - 13    Reserved
14        Client-originated (inbound) printer record
15        Server-originated (outbound) printer record
  • Byte 6: the length of the printer pass-through header, this field included (LL) πŸ“
  • Bytes 7-8: flags 🚩 byte 7 is where the drama is:
BYTE 7 BITS:  xxxx x111 --> Reserved
              xxxx 1xxx --> Last of chain
              xxx1 xxxx --> First of chain
              xx1x xxxx --> Printer now ready
              x1xx xxxx --> Intervention Required
              1xxx xxxx --> Error Indicator

BYTE 8 BITS:  xxxx xxxx --> Reserved
  • Byte 9: the printer operation code 🎬 '01'X means Print/Print complete, and '02'X means Clear Print Buffers
  • Bytes 10-LL: diagnostic information 🩺 (see Note 1 below)

the diagnostic bytes depend on what's going on in byte 7 πŸ” here's the tea:

If byte 7 is xx1x xxxx, bytes 10-LL may contain:

Printer ready                C9 00 00 00 02

If byte 7 is x1xx xxxx, bytes 10-LL may contain (see Note 2):

Command/parameter not valid  C9 00 03 02 2x
Print check                  C9 00 03 02 3x
Forms check                  C9 00 03 02 4x
Normal periodic condition    C9 00 03 02 5x
Data stream error            C9 00 03 02 6x
Machine/print/ribbon check   C9 00 03 02 8x

If byte 7 is 1xxx xxxx, bytes 10-LL may contain (see Note 3):

Cancel                       08 11 02 00
Invalid print parameter      08 11 02 29
Invalid print command        08 11 02 28

here are the notes for all that diagnostic info πŸ“

  1. LL is the length of the structure defined in byte 6 πŸ“ if there's no extra data, the rest of the structure must be padded with zeroes 🫢
  2. these are printer SIGNAL commands πŸ“‘ if you want the full scoop, check out the 5494 Remote Control Unit Functions Reference guide [5494-CU]. also look at your iSeries printer docs for the specifics on these data stream exceptions. the 3812 and 5553 errors you might bump into include:
Machine check              C9 00 03 02 11
Graphics check             C9 00 03 02 26
Print check               C9 00 03 02 31
Form jam                   C9 00 03 02 41
Paper jam                  C9 00 03 02 47
End of forms               C9 00 03 02 50
Printer not ready          C9 00 03 02 51
Data stream - class 1      C9 00 03 02 66 loss of text
Data stream - class 2      C9 00 03 02 67 text appearance
Data stream - class 3      C9 00 03 02 68 multibyte control error
Data stream - class 4      C9 00 03 02 69 multibyte control parm
Cover unexpectedly open    C9 00 03 02 81
Machine check              C9 00 03 02 86
Machine check              C9 00 03 02 87
Ribbon check               C9 00 03 02 88
  1. these are printer negative responses πŸ™…β€β™€οΈ for more on these commands, check the 5494 Remote Control Unit Functions Reference guide [5494-CU] again

and the print data starts at byte LL+1 πŸ’Œ

11.1. Example of a Print Record

okay this is the server sending the client some data with a print record πŸ–¨οΈ it usually shows up right after a Success Response Record, like the one in Figure 1 ✨

+--------------------------------------------------------------------+
|   +-- Length of structure (LLLL)                                   |
|   |    +-- GDS identifier                                          |
|   |    |    +-- Data flow record                                   |
|   |    |    |   +-- Length of pass-through specific header (LL)    |
|   |    |    |   |   +-- Flags                                      |
|   |    |    |   |   |   +-- Printer operation code                 |
|   |    |    |   |   |   |      +-- Zero pad to LL specified (0A)   |
|   |    |    |   |   |   |      |            +-- Printer data       |
|   |    |    |   |   |   |      |            |                      |
| +--+ +--+ +--+ ++ +--+ ++ +----------+ +---------------------------|
| |  | |  | |  | || |  | || |          | |                           |
| 0085 12A0 0101 0A 1800 01 000000000000 34C4012BD20345FF2BD2044C0002|
|                                                                    |
| ------------------------------------------------------------       |
|                                                                    |
| 2BD2040D00002BD20A8501010201030204022BD20309022BD2061100014A       |
|                                                                    |
| ------------------------------------------------------------       |
|                                                                    |
| 402BD20601010000012BD306F60000FFFF2BD20A48000001000000010100       |
|                                                                    |
| ------------------------------------------------------------       |
|                                                                    |
| 2BD10705000B0090012BD2044900F02BD206404A403DE02BD2041500F034       |
|                                                                    |
|    end of printer data                                             |
| -------------------------+                                         |
|                          |                                         |
| C4012BD10381FF002BC8034001                                         |
+--------------------------------------------------------------------+

        Figure 4.  Server sending client data with a print record

here's the breakdown of that example πŸ”Ž

  • '0085'X = logical record length, this byte included (LLLL) πŸ“
  • '12A0'X = GDS LU6.2 header πŸ†”
  • '0101'X = data flow record (server to client) 🌊
  • '0A'X = length of pass-through specific header (LL) πŸ“
  • '1800'X = first of chain / last of chain indicators ⛓️
  • '01'X = Print πŸ–¨οΈ
  • '000000000000'X = zero pad header to LL specified 🫧
  • '34C401'X = first piece of data for spooled data πŸ“¦
  • everything after that is printer data, commands, and orders πŸ’…

11.2. Example of a Print Complete Record

okay now the client sends the server a print complete record βœ… this normally follows a print record like the one in Figure 4 πŸŽ€ it means the print request wrapped up successfully πŸ₯³

+-------------------------------------------------------------------+
|   +-- Length of structure (LLLL)                                  |
|   |    +-- GDS identifier                                         |
|   |    |    +-- Data flow record                                  |
|   |    |    |   +-- Length of pass-through specific header (LL)   |
|   |    |    |   |   +-- Flags                                     |
|   |    |    |   |   |   +-- Printer operation code                |
|   |    |    |   |   |   |                                         |
| +--+ +--+ +--+ ++ +--+ ++                                         |
| |  | |  | |  | || |  | ||                                         |
| 000A 12A0 0102 04 0000 01                                         |
+-------------------------------------------------------------------+

      Figure 5.  Client sending server a print complete record

and the field breakdown 🧾

  • '000A'X = logical record length, this byte included (LLLL) πŸ“
  • '12A0'X = GDS LU6.2 header πŸ†”
  • '0102'X = data flow response record (client to server) 🌊
  • '04'X = length of pass-through specific header (LL) πŸ“
  • '0000'X = Good Response πŸ’―
  • '01'X = Print Complete πŸŽ‰

11.3. Example of a Null Print Record ✨

Okay bestie, Figure 6 is the server sending the client a null print record πŸ’… This is the very last print command the server sends for a print job. It's basically the server telling the printer "no more data, we're done here" 🫢 The null data byte '00'X is optional, and sometimes it can be left out (this happens in DBCS print streams, so iykyk πŸ™ˆ).

This example would normally come after any number of print records, like the one in Figure 4 πŸ–¨οΈ It means the print job finished successfully πŸŽ€ The client usually replies to this null print record with another print complete record, like the one in Figure 5 πŸ¦‹

   +------------------------------------------------------------------+
   |   +-- Length of structure (LLLL)                                 |
   |   |    +-- GDS identifier                                        |
   |   |    |    +-- Data flow record                                 |
   |   |    |    |   +-- Length of pass-through specific header (LL)  |
   |   |    |    |   |   +-- Flags                                    |
   |   |    |    |   |   |   +-- Printer operation code               |
   |   |    |    |   |   |   |      +-- Zero pad to LL specified (0A) |
   |   |    |    |   |   |   |      |        +-- Printer data         |
   |   |    |    |   |   |   |      |        |                        |
   | +--+ +--+ +--+ ++ +--+ ++ +----------+ ++                        |
   | |  | |  | |  | || |  | || |          | ||                        |
   | 0011 12A0 0101 0A 0800 01 000000000000 00                        |
   +------------------------------------------------------------------+
           Figure 6.  Server sending client a null print record

Here's the breakdown of every piece, no cap πŸ’–

  • '0011'X = Logical record length, including this byte ✨
  • '12A0'X = GDS LU6.2 header 🌈
  • '0101'X = Data flow record 🧚
  • '0A'X = Length of pass-through specific header (LL) 🌸
  • '0800'X = Last of Chain πŸ‘‘
  • '01'X = Print πŸ–¨οΈ
  • '000000000000'X = Zero pad header to LL specified πŸ’œ
  • '00'X = Null data byte 🫢

12. End-to-End Print Example ✨

okay bestie, this one is the whole print job from start to finish πŸ–¨οΈπŸ’– Picture a Telnet client and server doing a full exchange for a 526 byte spooled file. To make it easier to read, the hex streams are split up: the Telnet negotiations are wrapped in '(' and ')', and the ASCII/EBCDIC characters are wrapped in '|' vertical bars. The raw hex stays on the left so you can see the actual bytes ✨


iSeries Telnet server               Enhanced Telnet client
-------------------------------     ---------------------------------
FFFD27                          -->

(IAC DO NEW-ENVIRON)
                                <-- FFFB27

                                    (IAC WILL NEW-ENVIRON)

FFFD18FFFA270103 49424D5253454544
7EA5DFDDFD300404 0003FFF0       -->

(IAC DO TERMINAL-TYPE
IAC SB NEW-ENVIRON SEND USERVAR
IBMRSEED xxxxxxxx VAR USERVAR
IAC SE)

                                <-- FFFB18

                                    (IAC WILL TERMINAL-TYPE)

FFFA1801FFF0                    -->

(IAC SB TERMINAL-TYPE SEND IAC
 SE)

                                    FFFA27000349424D 52534545447EA5DF
                                    DDFD300404000344 45564E414D450144
                                    554D4D5950525403 49424D4D5347514E
                                    414D450151535953 4F50520349424D4D
                                    5347514C4942012A 4C49424C0349424D
                                    464F4E5401313103 49424D5452414E53
                                    464F524D01310349 424D4D4652545950
                                    4D444C012A485049 490349424D505052
                                    5352433101020103 49424D5050525352
                                    433201040349424D 454E56454C4F5045
                                    01FFFF0349424D41 5343494938393901
                                <-- 30FFF0

                                    (IAC SB NEW-ENVIRON IS USERVAR
                                     IBMRSEED xxxxxxxx VAR
                                     USERVAR DEVNAME VALUE DUMMYPRT
                                     USERVAR IBMMSGQNAME VALUE
                                     QSYSOPR
                                     USERVAR IBMMSGQLIB VALUE *LIBL
                                     USERVAR IBMFONT VALUE 11
                                     USERVAR IBMTRANSFORM VALUE 1
                                     USERVAR IBMMFRTYPMDL VALUE *HPII
                                     USERVAR IBMPPRSRC1 VALUE
                                     ESC '01'X
                                     USERVAR IBMPPRSRC2 VALUE '04'X
                                     USERVAR IBMENVELOPE VALUE IAC
                                     USERVAR IBMASCII899 VALUE 0
                                     IAC SE)

                                <-- FFFA180049424D2D 333831322D31FFF0

                                    (IAC SB TERMINAL-TYPE IS
                                     IBM-3812-1 IAC SE)
FFFD19                          -->

(IAC DO EOR)
                                <-- FFFB19

                                    (IAC WILL EOR)

FFFB19                          -->

(IAC WILL EOR)
                                <-- FFFD19

                                    (IAC DO EOR)
FFFD00                          -->

(IAC DO BINARY)
                                <-- FFFB00

                                    (IAC WILL BINARY)
FFFB00                          -->

(IAC WILL BINARY)
                                <-- FFFD00

                                    (IAC DO BINARY)

004912A090000560 060020C0003D0000     |       -   {    |
C9F9F0F2C5D3C3D9 E3D7F0F6C4E4D4D4     |I902ELCRTP06DUMM| (EBCDIC)
E8D7D9E340400000 0000000000000000     |YPRT            |
0000000000000000 0000000000000000     |                |
0000000000000000 00FFEF           --> |                |

(73-byte startup success response
 record ... IAC EOR)
00DF12A001010A18 0001000000000000     |                |
03CD1B451B283130 551B287330703130     |   E (10U (s0p10| (ASCII)
2E30306831327630 733062303033541B     |.00h12v0s0b003T |
287330421B266440 1B266C304F1B266C     |(s0B &d@ &l0O &l|
303038431B266C30 3035431B28733070     |008C &l005C (s0p|
31372E3130683130 7630733062303030     |17.10h10v0s0b000|
541B283130551B28 73307031372E3130     |T (10U (s0p17.10|
6831307630733062 303030541B287330     |h10v0s0b000T (s0|
421B2664401B266C 314F1B266C303035     |B &d@ &l1O &l005|
431B287330703137 2E31306831307630     |C (s0p17.10h10v0|
733062303030541B 266C314F1B287330     |s0b000T &l1O (s0|
7031372E31306831 3076307330623030     |p17.10h10v0s0b00|
30541B2873307031 372E313068313076     |0T (s0p17.10h10v|
3073306230303054 1B266C30303543FF     |0s0b000T &l005C |
EF                                --> |                |

(... 223-byte print record ...
 ... first of chain ...
 ... last of chain ... IAC EOR)
                                  <-- 000A12A001020400 0001FFEF

                                      (10-byte print complete header)
031012A001010A10 0001000000000000     |                |
03FFFF1B451B2831 30551B2873307031     |    E (10U (s0p1| (ASCII)
372E313068313076 3073306230303054     |7.10h10v0s0b000T|
1B287330421B2664 401B266C314F1B26     | (s0B &d@ &l1O &|
6C303035431B266C 31481B266C314F1B     |l005C &l1H &l1O |
266C3032411B266C 31431B266C303030     |&l02A &l1C &l000|
38451B266C303038 431B266C30303439     |8E &l008C &l0049|
461B266130521B26 6C303035430A0A0A     |F &a0R &l005C   |
0A0A0A0A1B26612B 3030303130561B26     |     &a+00010V &|
6C303035431B2661 2B30303231364820     |l005C &a+00216H |
2020202020202020 2020202020202020     |                |
2020202020205072 696E74204B657920     |      Print Key |
4F75747075742020 2020202020202020     |Output          |
2020202020202020 2020202020202020     |                |
2020202020205061 6765202020310D0A     |      Page   1  |
1B26612B30303231 3648202020203537     | &a+00216H    57|
3639535331205634 52334D3020393830     |69SS1 V4R3M0 980|
373203FFFF392020 2020202020202020     |72   9          |
202020202020454C 4352545030362020     |      ELCRTP06  |
2020202020202020 202030332F33312F     |          03/31/|
3939202031363A33 303A34350D0A1B26     |99  16:30:45   &|
612B303032313648 0D0A1B26612B3030     |a+00216H   &a+00|
3231364820202020 446973706C617920     |216H    Display |
4465766963652020 2E202E202E202E20     |Device  . . . . |
2E203A2020515041 444556303033510D     |. :  QPADEV003Q |
0A1B26612B303032 3136482020202055     |  &a+00216H    U|
73657220202E202E 202E202E202E202E     |ser  . . . . . .|
202E202E202E202E 203A202052434153     | . . . . :  RCAS|
54524F0D0A1B2661 2B3030323136480D     |TRO   &a+00216H |
0A1B26612B303032 313648204D41494E     |  &a+00216H MAIN|
2020202020202020 2020202020202020     |                |
2020202020202020 20202041532F3430     |           AS/40|
30204D61696E204D 656E750D0A1B2661     |0 Main Menu   &a|
2B30303203FFFF31 3648202020202020     |+002   16H      |
2020202020202020 2020202020202020     |                |
2020202020202020 2020202020202020     |                |
2020202020202020 2020202020202020     |                |
2020202020202053 797374656D3A2020     |       System:  |
20454C4352545030 360D0A1B26612B30     | ELCRTP06   &a+0|
3032313648205365 6C656374206F6E65     |0216H Select one|
206F662074686520 666F6C6C6F77696E     | of the followin|
673A0D0A1B26612B 3030323136480D0A     |g:   &a+00216H  |
1B26612B30303231 3648202020202020     | &a+00216H      |
312E205573657220 7461736B730D0A1B     |1. User tasks   |
26612B3030323136 4820202020202032     |&a+00216H      2|
2E204F6666696365 207461736B730D0A     |. Office tasks  |
1B26612B30303231 36480D0A1B26612B     | &a+00216H   &a+|
3030323136482020 20202020342E2046     |00216H      4. F|
696C65732C206C69 627261726965732C     |iles, libraries,|
20616EFFEF                            | an             |

(... 784-byte print record ...
 ... first of chain ... IAC EOR)
                                  <-- 000A12A001020400 0001FFEF

                                      (10-byte print complete header)

020312A001010A00 0001000000000000     |                |
64206603FFFF6F6C 646572730D0A1B26     |d f   olders   &| (ASCII)
612B303032313648 0D0A1B26612B3030     |a+00216H   &a+00|
3231364820202020 2020362E20436F6D     |216H      6. Com|
6D756E6963617469 6F6E730D0A1B2661     |munications   &a|
2B3030323136480D 0A1B26612B303032     |+00216H   &a+002|
3136482020202020 20382E2050726F62     |16H      8. Prob|
6C656D2068616E64 6C696E670D0A1B26     |lem handling   &|
612B303032313648 202020202020392E     |a+00216H      9.|
20446973706C6179 2061206D656E750D     | Display a menu |
0A1B26612B303032 3136482020202020     |  &a+00216H     |
31302E20496E666F 726D6174696F6E20     |10. Information |
417373697374616E 74206F7074696F6E     |Assistant option|
730D0A1B26612B30 3032313648202020     |s   &a+00216H   |
202031312E20436C 69656E7420416363     |  11. Client Acc|
6573732F34303020 7461736B730D0A1B     |ess/400 tasks   |
26612B3030323136 480D0A1B26612B30     |&a+00216H   &a+0|
303231364803ED20 2020202039302E20     |0216H       90. |
5369676E206F6666 0D0A1B26612B3030     |Sign off   &a+00|
323136480D0A1B26 612B303032313648     |216H   &a+00216H|
2053656C65637469 6F6E206F7220636F     | Selection or co|
6D6D616E640D0A1B 26612B3030323136     |mmand   &a+00216|
48203D3D3D3E0D0A 1B26612B30303231     |H ===>   &a+0021|
36480D0A1B26612B 3030323136482046     |6H   &a+00216H F|
333D457869742020 2046343D50726F6D     |3=Exit   F4=Prom|
707420202046393D 5265747269657665     |pt   F9=Retrieve|
2020204631323D43 616E63656C202020     |   F12=Cancel   |
4631333D496E666F 726D6174696F6E20     |F13=Information |
417373697374616E 740D0A1B26612B30     |Assistant   &a+0|
3032313648204632 333D53657420696E     |0216H F23=Set in|
697469616C206D65 6E750D0A1B26612B     |itial menu   &a+|
3030323136480D0A 1B26612B30303231     |00216H   &a+0021|
36480D0CFFEF                          |6H              |

(... 515-byte print record ...
 IAC EOR)
                                  <-- 000A12A001020400 0001FFEF

                                      (10-byte print complete header)
001412A001010A00 0001000000000000     |                |
03021B45FFEF                          |   E            |  (ASCII)

(... 20-byte print record ...
 IAC EOR)
                                  <-- 000A12A001020400 0001FFEF

                                      (10-byte print complete header)
001112A001010A08 0001000000000000
00FFEF                            -->

(... 17-byte NULL print record ...
 ... last of chain ... IAC EOR)
                                  <-- 000A12A001020400 0001FFEF

                                      (10-byte print complete header)

13. Security Considerations πŸ”

okay bestie, this part is important 😭 The auto-sign-on feature in this RFC is a way to encrypt your login password πŸ”‘ With the IBMRSEED and IBMSUBSPW USERVAR negotiations, passwords can be encrypted now. BUT (and this is the lowkey scary part) only the login passwords get encrypted, NOT the whole Telnet session. If you want the entire session encrypted, you need another protocol layer on top, like SSL πŸ”’

The auto-sign-on feature supports plain text passwords, encrypted passwords, and Kerberos tokens 🎟️ Using plain text passwords is strongly discouraged πŸ™…β€β™€οΈ iSeries system admins may want to configure their systems to reject plain text passwords. Main character energy for security πŸ’…

⚠️ Only the login password is protected by this feature. The rest of the Telnet session is not encrypted unless another layer such as SSL is added. Plain text passwords should be avoided whenever possible.

14. IANA Considerations πŸ¦‹

IANA registered the terminal types "IBM-3812-1" and "IBM-5553-B01" as a terminal type [RFC1091] ✨ They're used when talking to iSeries Telnet servers. Iconic registry moment πŸ‘‘

15. Normative References πŸ“š

These are the must-read references for this one 🫢

[RFC854]      Postel, J. and J. Reynolds, "Telnet Protocol
              Specification", STD 8, RFC 854, May 1983.

[RFC855]      Postel, J. and J. Reynolds, "Telnet Option
              Specifications", STD 8, RFC 855, May 1983.

[RFC1091]     VanBokkelen, J., "Telnet terminal-type option", RFC
              1091, February 1989.

[RFC1205]     Chmielewski, P., "5250 Telnet Interface", RFC 1205,
              February 1991.

[RFC1572]     Alexander, S., "Telnet Environment Option", RFC 1572,
              January 1994.

[RFC2877]     Murphy, T., Jr., Rieth, P., and J. Stevens, "5250
              Telnet Enhancements", RFC 2877, July 2000.

16. Informative References 🧚

Extra reading if you're curious 🌸

[RFC856]      Postel, J. and J. Reynolds, "Telnet Binary
              Transmission", STD 27, RFC 856, May 1983.

[RFC858]      Postel, J. and J. Reynolds, "Telnet Supress Go Ahead
              Option", STD 29, RFC 858, May 1983.

[RFC885]      Postel, J., "Telnet end of record option", RFC 885,
              December 1983.

[5494-CU]     IBM, "5494 Remote Control Unit, Functions Reference",
              SC30-3533-04, August 1995.

[SYSTEM-API]  IBM, "AS/400 System API Reference", SC41-5801-01,
              February 1998.

[COMM-CONFIG] IBM, "AS/400 Communications Configuration",
              SC41-5401-00, August 1997.

[NLS-SUPPORT] IBM, "AS/400 National Language Support", SC41-5101-01,
              February 1998.

[FIPS-46-2]   Data Encryption Standard (DES), Federal Information
              Processing Standards Publication 46-2, January 22,
              1988.

[FIPS-81]     DES Modes of Operation, Federal Information Processing
              Standards Publication 81, December 1980.

[FIPS-180-1]  Secure Hash Standard, Federal Information Processing
              Standards Publication 180-1, May 11, 1993.

17. Relation to Other RFCs πŸ’–

This RFC relies on the 5250 Telnet Interface [RFC1205] in all examples ✨

This RFC replaces 5250 Telnet Enhancements [RFC2877] πŸ”₯ It adds new sections for Kerberos, SHA-1, security and IANA considerations. Minor corrections and extra examples were added too.

Informative references have been removed 🧹


Authors' Addresses πŸ–‹οΈ

Meet the IBM crew who made this happen πŸ’œ

Thomas E. Murphy, Jr.
IBM Corporation
2455 South Road
Poughkeepsie, NY 12601

Phone:  (845) 435-7063
Fax:    (845) 432-9414
EMail:  murphyte@us.ibm.com


Paul F. Rieth
IBM Corporation
3605 Highway 52 North
Rochester, MN 55901

Phone:  (507) 253-5218
Fax:    (507) 253-5156
EMail:  rieth@us.ibm.com


Jeffrey S. Stevens
IBM Corporation
3605 Highway 52 North
Rochester, MN 55901

Phone:  (507) 253-5337
Fax:    (507) 253-5156
EMail:  jssteven@us.ibm.com

Copyright (C) The IETF Trust (2006) 🌈

This document is subject to the rights, licenses and restrictions in BCP 78 and at www.rfc-editor.org/copyright.html. Except as set forth there, the authors keep all their rights πŸŽ€

This document and the information in it are provided on an "AS IS" basis, and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST, AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property πŸ¦„

The IETF doesn't take a position on whether any Intellectual Property Rights (or other rights) claimed to cover this technology are valid, what their scope is, or whether any license is available. It also doesn't say it has independently searched for those rights. Info on how rights work for RFC documents is in BCP 78 and BCP 79 πŸ“–

IPR disclosures sent to the IETF Secretariat, assurances of licenses, and results of attempts to get a general license for implementers or users are available from the IETF's online IPR repository at http://www.ietf.org/ipr πŸ”Ž

The IETF also invites anyone to flag copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to implement this standard. Send that to the IETF at ietf-ipr@ietf.org πŸ’Œ

Acknowledgement 🌷

Funding for the RFC Editor function is currently provided by the Internet Society 🫢✨

πŸ“¦ where this page comes from