forked from arichardson/openssh-portable
-
Notifications
You must be signed in to change notification settings - Fork 1
/
RFC.nroff
1780 lines (1586 loc) · 71 KB
/
RFC.nroff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
.\" -*- nroff -*-
.\"
.\" $OpenBSD: RFC.nroff,v 1.2 2000/10/16 09:38:44 djm Exp $
.\"
.pl 10.0i
.po 0
.ll 7.2i
.lt 7.2i
.nr LL 7.2i
.nr LT 7.2i
.ds LF Ylonen
.ds RF FORMFEED[Page %]
.ds CF
.ds LH Internet-Draft
.ds RH 15 November 1995
.ds CH SSH (Secure Shell) Remote Login Protocol
.na
.hy 0
.in 0
Network Working Group T. Ylonen
Internet-Draft Helsinki University of Technology
draft-ylonen-ssh-protocol-00.txt 15 November 1995
Expires: 15 May 1996
.in 3
.ce
The SSH (Secure Shell) Remote Login Protocol
.ti 0
Status of This Memo
This document is an Internet-Draft. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six
months and may be updated, replaced, or obsoleted by other docu-
ments at any time. It is inappropriate to use Internet-Drafts as
reference material or to cite them other than as ``work in pro-
gress.''
To learn the current status of any Internet-Draft, please check the
``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow
Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe),
munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or
ftp.isi.edu (US West Coast).
The distribution of this memo is unlimited.
.ti 0
Introduction
SSH (Secure Shell) is a program to log into another computer over a
network, to execute commands in a remote machine, and to move files
from one machine to another. It provides strong authentication and
secure communications over insecure networks. Its features include
the following:
.IP o
Closes several security holes (e.g., IP, routing, and DNS spoofing).
New authentication methods: .rhosts together with RSA [RSA] based host
authentication, and pure RSA authentication.
.IP o
All communications are automatically and transparently encrypted.
Encryption is also used to protect integrity.
.IP o
X11 connection forwarding provides secure X11 sessions.
.IP o
Arbitrary TCP/IP ports can be redirected over the encrypted channel
in both directions.
.IP o
Client RSA-authenticates the server machine in the beginning of every
connection to prevent trojan horses (by routing or DNS spoofing) and
man-in-the-middle attacks, and the server RSA-authenticates the client
machine before accepting .rhosts or /etc/hosts.equiv authentication
(to prevent DNS, routing, or IP spoofing).
.IP o
An authentication agent, running in the user's local workstation or
laptop, can be used to hold the user's RSA authentication keys.
.RT
The goal has been to make the software as easy to use as possible for
ordinary users. The protocol has been designed to be as secure as
possible while making it possible to create implementations that
are easy to use and install. The sample implementation has a number
of convenient features that are not described in this document as they
are not relevant for the protocol.
.ti 0
Overview of the Protocol
The software consists of a server program running on a server machine,
and a client program running on a client machine (plus a few auxiliary
programs). The machines are connected by an insecure IP [RFC0791]
network (that can be monitored, tampered with, and spoofed by hostile
parties).
A connection is always initiated by the client side. The server
listens on a specific port waiting for connections. Many clients may
connect to the same server machine.
The client and the server are connected via a TCP/IP [RFC0793] socket
that is used for bidirectional communication. Other types of
transport can be used but are currently not defined.
When the client connects the server, the server accepts the connection
and responds by sending back its version identification string. The
client parses the server's identification, and sends its own
identification. The purpose of the identification strings is to
validate that the connection was to the correct port, declare the
protocol version number used, and to declare the software version used
on each side (for debugging purposes). The identification strings are
human-readable. If either side fails to understand or support the
other side's version, it closes the connection.
After the protocol identification phase, both sides switch to a packet
based binary protocol. The server starts by sending its host key
(every host has an RSA key used to authenticate the host), server key
(an RSA key regenerated every hour), and other information to the
client. The client then generates a 256 bit session key, encrypts it
using both RSA keys (see below for details), and sends the encrypted
session key and selected cipher type to the server. Both sides then
turn on encryption using the selected algorithm and key. The server
sends an encrypted confirmation message to the client.
The client then authenticates itself using any of a number of
authentication methods. The currently supported authentication
methods are .rhosts or /etc/hosts.equiv authentication (disabled by
default), the same with RSA-based host authentication, RSA
authentication, and password authentication.
After successful authentication, the client makes a number of requests
to prepare for the session. Typical requests include allocating a
pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting
authentication agent forwarding, and executing the shell or a command.
When a shell or command is executed, the connection enters interactive
session mode. In this mode, data is passed in both directions,
new forwarded connections may be opened, etc. The interactive session
normally terminates when the server sends the exit status of the
program to the client.
The protocol makes several reservations for future extensibility.
First of all, the initial protocol identification messages include the
protocol version number. Second, the first packet by both sides
includes a protocol flags field, which can be used to agree on
extensions in a compatible manner. Third, the authentication and
session preparation phases work so that the client sends requests to
the server, and the server responds with success or failure. If the
client sends a request that the server does not support, the server
simply returns failure for it. This permits compatible addition of
new authentication methods and preparation operations. The
interactive session phase, on the other hand, works asynchronously and
does not permit the use of any extensions (because there is no easy
and reliable way to signal rejection to the other side and problems
would be hard to debug). Any compatible extensions to this phase must
be agreed upon during any of the earlier phases.
.ti 0
The Binary Packet Protocol
After the protocol identification strings, both sides only send
specially formatted packets. The packet layout is as follows:
.IP o
Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb
first. Gives the length of the packet, not including the length field
and padding. The maximum length of a packet (not including the length
field and padding) is 262144 bytes.
.IP o
Padding: 1-8 bytes of random data (or zeroes if not encrypting). The
amount of padding is (8 - (length % 8)) bytes (where % stands for the
modulo operator). The rationale for always having some random padding
at the beginning of each packet is to make known plaintext attacks
more difficult.
.IP o
Packet type: 8-bit unsigned byte. The value 255 is reserved for
future extension.
.IP o
Data: binary data bytes, depending on the packet type. The number of
data bytes is the "length" field minus 5.
.IP o
Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the
Cyclic Redundancy Check, with the polynomial 0xedb88320, of the
Padding, Packet type, and Data fields. The crc is computed before
any encryption.
.RT
The packet, except for the length field, may be encrypted using any of
a number of algorithms. The length of the encrypted part (Padding +
Type + Data + Check) is always a multiple of 8 bytes. Typically the
cipher is used in a chained mode, with all packets chained together as
if it was a single data stream (the length field is never included in
the encryption process). Details of encryption are described below.
When the session starts, encryption is turned off. Encryption is
enabled after the client has sent the session key. The encryption
algorithm to use is selected by the client.
.ti 0
Packet Compression
If compression is supported (it is an optional feature, see
SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields
of the packet are compressed using the gzip deflate algorithm [GZIP].
If compression is in effect, the packet length field indicates the
length of the compressed data, plus 4 for the crc. The amount of
padding is computed from the compressed data, so that the amount of
data to be encrypted becomes a multiple of 8 bytes.
When compressing, the packets (type + data portions) in each direction
are compressed as if they formed a continuous data stream, with only the
current compression block flushed between packets. This corresponds
to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression
dictionary is not flushed between packets. The two directions are
compressed independently of each other.
.ti 0
Packet Encryption
The protocol supports several encryption methods. During session
initialization, the server sends a bitmask of all encryption methods
that it supports, and the client selects one of these methods. The
client also generates a 256-bit random session key (32 8-bit bytes) and
sends it to the server.
The encryption methods supported by the current implementation, and
their codes are:
.TS
center;
l r l.
SSH_CIPHER_NONE 0 No encryption
SSH_CIPHER_IDEA 1 IDEA in CFB mode
SSH_CIPHER_DES 2 DES in CBC mode
SSH_CIPHER_3DES 3 Triple-DES in CBC mode
SSH_CIPHER_TSS 4 An experimental stream cipher
SSH_CIPHER_RC4 5 RC4
.TE
All implementations are required to support SSH_CIPHER_DES and
SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and
SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is
optional (and it is not described in this document). Other ciphers
may be added at a later time; support for them is optional.
For encryption, the encrypted portion of the packet is considered a
linear byte stream. The length of the stream is always a multiple of
8. The encrypted portions of consecutive packets (in the same
direction) are encrypted as if they were a continuous buffer (that is,
any initialization vectors are passed from the previous packet to the
next packet). Data in each direction is encrypted independently.
.IP SSH_CIPHER_DES
The key is taken from the first 8 bytes of the session key. The least
significant bit of each byte is ignored. This results in 56 bits of
key data. DES [DES] is used in CBC mode. The iv (initialization vector) is
initialized to all zeroes.
.IP SSH_CIPHER_3DES
The variant of triple-DES used here works as follows: there are three
independent DES-CBC ciphers, with independent initialization vectors.
The data (the whole encrypted data stream) is first encrypted with the
first cipher, then decrypted with the second cipher, and finally
encrypted with the third cipher. All these operations are performed
in CBC mode.
The key for the first cipher is taken from the first 8 bytes of the
session key; the key for the next cipher from the next 8 bytes, and
the key for the third cipher from the following 8 bytes. All three
initialization vectors are initialized to zero.
(Note: the variant of 3DES used here differs from some other
descriptions.)
.IP SSH_CIPHER_IDEA
The key is taken from the first 16 bytes of the session key. IDEA
[IDEA] is used in CFB mode. The initialization vector is initialized
to all zeroes.
.IP SSH_CIPHER_TSS
All 32 bytes of the session key are used as the key.
There is no reference available for the TSS algorithm; it is currently
only documented in the sample implementation source code. The
security of this cipher is unknown (but it is quite fast). The cipher
is basically a stream cipher that uses MD5 as a random number
generator and takes feedback from the data.
.IP SSH_CIPHER_RC4
The first 16 bytes of the session key are used as the key for the
server to client direction. The remaining 16 bytes are used as the
key for the client to server direction. This gives independent
128-bit keys for each direction.
This algorithm is the alleged RC4 cipher posted to the Usenet in 1995.
It is widely believed to be equivalent with the original RSADSI RC4
cipher. This is a very fast algorithm.
.RT
.ti 0
Data Type Encodings
The Data field of each packet contains data encoded as described in
this section. There may be several data items; each item is coded as
described here, and their representations are concatenated together
(without any alignment or padding).
Each data type is stored as follows:
.IP "8-bit byte"
The byte is stored directly as a single byte.
.IP "32-bit unsigned integer"
Stored in 4 bytes, msb first.
.IP "Arbitrary length binary string"
First 4 bytes are the length of the string, msb first (not including
the length itself). The following "length" bytes are the string
value. There are no terminating null characters.
.IP "Multiple-precision integer"
First 2 bytes are the number of bits in the integer, msb first (for
example, the value 0x00012345 would have 17 bits). The value zero has
zero bits. It is permissible that the number of bits be larger than the
real number of bits.
The number of bits is followed by (bits + 7) / 8 bytes of binary data,
msb first, giving the value of the integer.
.RT
.ti 0
TCP/IP Port Number and Other Options
The server listens for connections on TCP/IP port 22.
The client may connect the server from any port. However, if the
client wishes to use any form of .rhosts or /etc/hosts.equiv
authentication, it must connect from a privileged port (less than
1024).
For the IP Type of Service field [RFC0791], it is recommended that
interactive sessions (those having a user terminal or forwarding X11
connections) use the IPTOS_LOWDELAY, and non-interactive connections
use IPTOS_THROUGHPUT.
It is recommended that keepalives are used, because otherwise programs
on the server may never notice if the other end of the connection is
rebooted.
.ti 0
Protocol Version Identification
After the socket is opened, the server sends an identification string,
which is of the form
"SSH-<protocolmajor>.<protocolminor>-<version>\\n", where
<protocolmajor> and <protocolminor> are integers and specify the
protocol version number (not software distribution version).
<version> is server side software version string (max 40 characters);
it is not interpreted by the remote side but may be useful for
debugging.
The client parses the server's string, and sends a corresponding
string with its own information in response. If the server has lower
version number, and the client contains special code to emulate it,
the client responds with the lower number; otherwise it responds with
its own number. The server then compares the version number the
client sent with its own, and determines whether they can work
together. The server either disconnects, or sends the first packet
using the binary packet protocol and both sides start working
according to the lower of the protocol versions.
By convention, changes which keep the protocol compatible with
previous versions keep the same major protocol version; changes that
are not compatible increment the major version (which will hopefully
never happen). The version described in this document is 1.3.
The client will
.ti 0
Key Exchange and Server Host Authentication
The first message sent by the server using the packet protocol is
SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public
key, supported ciphers, supported authentication methods, and flags
for protocol extensions. It also contains a 64-bit random number
(cookie) that must be returned in the client's reply (to make IP
spoofing more difficult). No encryption is used for this message.
Both sides compute a session id as follows. The modulus of the server
key is interpreted as a byte string (without explicit length field,
with minimum length able to hold the whole value), most significant
byte first. This string is concatenated with the server host key
interpreted the same way. Additionally, the cookie is concatenated
with this. Both sides compute MD5 of the resulting string. The
resulting 16 bytes (128 bits) are stored by both parties and are
called the session id.
The client responds with a SSH_CMSG_SESSION_KEY message, which
contains the selected cipher type, a copy of the 64-bit cookie sent by
the server, client's protocol flags, and a session key encrypted
with both the server's host key and server key. No encryption is used
for this message.
The session key is 32 8-bit bytes (a total of 256 random bits
generated by the client). The client first xors the 16 bytes of the
session id with the first 16 bytes of the session key. The resulting
string is then encrypted using the smaller key (one with smaller
modulus), and the result is then encrypted using the other key. The
number of bits in the public modulus of the two keys must differ by at
least 128 bits.
At each encryption step, a multiple-precision integer is constructed
from the data to be encrypted as follows (the integer is here
interpreted as a sequence of bytes, msb first; the number of bytes is
the number of bytes needed to represent the modulus).
The most significant byte (which is only partial as the value must be
less than the public modulus, which is never a power of two) is zero.
The next byte contains the value 2 (which stands for public-key
encrypted data in the PKCS standard [PKCS#1]). Then, there are
non-zero random bytes to fill any unused space, a zero byte, and the
data to be encrypted in the least significant bytes, the last byte of
the data in the least significant byte.
This algorithm is used twice. First, it is used to encrypt the 32
random bytes generated by the client to be used as the session key
(xored by the session id). This value is converted to an integer as
described above, and encrypted with RSA using the key with the smaller
modulus. The resulting integer is converted to a byte stream, msb
first. This byte stream is padded and encrypted identically using the
key with the larger modulus.
After the client has sent the session key, it starts to use the
selected algorithm and key for decrypting any received packets, and
for encrypting any sent packets. Separate ciphers are used for
different directions (that is, both directions have separate
initialization vectors or other state for the ciphers).
When the server has received the session key message, and has turned
on encryption, it sends a SSH_SMSG_SUCCESS message to the client.
The recommended size of the host key is 1024 bits, and 768 bits for
the server key. The minimum size is 512 bits for the smaller key.
.ti 0
Declaring the User Name
The client then sends a SSH_CMSG_USER message to the server. This
message specifies the user name to log in as.
The server validates that such a user exists, checks whether
authentication is needed, and responds with either SSH_SMSG_SUCCESS or
SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication
is needed for this user (no password), and authentication phase has
now been completed. SSH_SMSG_FAILURE indicates that authentication is
needed (or the user does not exist).
If the user does not exist, it is recommended that this returns
failure, but the server keeps reading messages from the client, and
responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE,
and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot
be certain whether the user exists.
.ti 0
Authentication Phase
Provided the server didn't immediately accept the login, an
authentication exchange begins. The client sends messages to the
server requesting different types of authentication in arbitrary order as
many times as desired (however, the server may close the connection
after a timeout). The server always responds with SSH_SMSG_SUCCESS if
it has accepted the authentication, and with SSH_SMSG_FAILURE if it has
denied authentication with the requested method or it does not
recognize the message. Some authentication methods cause an exchange
of further messages before the final result is sent. The
authentication phase ends when the server responds with success.
The recommended value for the authentication timeout (timeout before
disconnecting if no successful authentication has been made) is 5
minutes.
The following authentication methods are currently supported:
.TS
center;
l r l.
SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv
SSH_AUTH_RSA 2 pure RSA authentication
SSH_AUTH_PASSWORD 3 password authentication
SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication
.TE
.IP SSH_AUTH_RHOSTS
This is the authentication method used by rlogin and rsh [RFC1282].
The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name
as an argument.
The server checks whether to permit authentication. On UNIX systems,
this is usually done by checking /etc/hosts.equiv, and .rhosts in the
user's home directory. The connection must come from a privileged
port.
It is recommended that the server checks that there are no IP options
(such as source routing) specified for the socket before accepting
this type of authentication. The client host name should be
reverse-mapped and then forward mapped to ensure that it has the
proper IP-address.
This authentication method trusts the remote host (root on the remote
host can pretend to be any other user on that host), the name
services, and partially the network: anyone who can see packets coming
out from the server machine can do IP-spoofing and pretend to be any
machine; however, the protocol prevents blind IP-spoofing (which used
to be possible with rlogin).
Many sites probably want to disable this authentication method because
of the fundamental insecurity of conventional .rhosts or
/etc/hosts.equiv authentication when faced with spoofing. It is
recommended that this method not be supported by the server by
default.
.IP SSH_AUTH_RHOSTS_RSA
In addition to conventional .rhosts and hosts.equiv authentication,
this method additionally requires that the client host be
authenticated using RSA.
The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side
user name, and the public host key of the client host.
The server first checks if normal .rhosts or /etc/hosts.equiv
authentication would be accepted, and if not, responds with
SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key
for the client machine (using the same name for the host that was used
for checking the .rhosts and /etc/hosts.equiv files). If it does not
know the RSA key for the client, access is denied and SSH_SMSG_FAILURE
is sent.
If the server knows the host key of the client machine, it verifies
that the given host key matches that known for the client. If not,
access is denied and SSH_SMSG_FAILURE is sent.
The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing
an encrypted challenge for the client. The challenge is 32 8-bit
random bytes (256 bits). When encrypted, the highest (partial) byte
is left as zero, the next byte contains the value 2, the following are
non-zero random bytes, followed by a zero byte, and the challenge put
in the remaining bytes. This is then encrypted using RSA with the
client host's public key. (The padding and encryption algorithm is
the same as that used for the session key.)
The client decrypts the challenge using its private host key,
concatenates this with the session id, and computes an MD5 checksum
of the resulting 48 bytes. The MD5 output is returned as 16 bytes in
a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen
plaintext attacks against RSA; the session id binds it to a specific
session).
The server verifies that the MD5 of the decrypted challenge returned by
the client matches that of the original value, and sends SSH_SMSG_SUCCESS if
so. Otherwise it sends SSH_SMSG_FAILURE and refuses the
authentication attempt.
This authentication method trusts the client side machine in that root
on that machine can pretend to be any user on that machine.
Additionally, it trusts the client host key. The name and/or IP
address of the client host is only used to select the public host key.
The same host name is used when scanning .rhosts or /etc/hosts.equiv
and when selecting the host key. It would in principle be possible to
eliminate the host name entirely and substitute it directly by the
host key. IP and/or DNS [RFC1034] spoofing can only be used
to pretend to be a host for which the attacker has the private host
key.
.IP SSH_AUTH_RSA
The idea behind RSA authentication is that the server recognizes the
public key offered by the client, generates a random challenge, and
encrypts the challenge with the public key. The client must then
prove that it has the corresponding private key by decrypting the
challenge.
The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an
argument.
The server may respond immediately with SSH_SMSG_FAILURE if it does
not permit authentication with this key. Otherwise it generates a
challenge, encrypts it using the user's public key (stored on the
server and identified using the modulus), and sends
SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an
argument.
The challenge is 32 8-bit random bytes (256 bits). When encrypted,
the highest (partial) byte is left as zero, the next byte contains the
value 2, the following are non-zero random bytes, followed by a zero
byte, and the challenge put in the remaining bytes. This is then
encrypted with the public key. (The padding and encryption algorithm
is the same as that used for the session key.)
The client decrypts the challenge using its private key, concatenates
it with the session id, and computes an MD5 checksum of the resulting
48 bytes. The MD5 output is returned as 16 bytes in a
SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary
to avoid chosen plaintext attacks against RSA; the session id binds it
to a specific session.)
The server verifies that the MD5 of the decrypted challenge returned
by the client matches that of the original value, and sends
SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and
refuses the authentication attempt.
This authentication method does not trust the remote host, the
network, name services, or anything else. Authentication is based
solely on the possession of the private identification keys. Anyone
in possession of the private keys can log in, but nobody else.
The server may have additional requirements for a successful
authentiation. For example, to limit damage due to a compromised RSA
key, a server might restrict access to a limited set of hosts.
.IP SSH_AUTH_PASSWORD
The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text
password. (Note that even though the password is plain text inside
the message, it is normally encrypted by the packet mechanism.)
The server verifies the password, and sends SSH_SMSG_SUCCESS if
authentication was accepted and SSH_SMSG_FAILURE otherwise.
Note that the password is read from the user by the client; the user
never interacts with a login program.
This authentication method does not trust the remote host, the
network, name services or anything else. Authentication is based
solely on the possession of the password. Anyone in possession of the
password can log in, but nobody else.
.RT
.ti 0
Preparatory Operations
After successful authentication, the server waits for a request from
the client, processes the request, and responds with SSH_SMSG_SUCCESS
whenever a request has been successfully processed. If it receives a
message that it does not recognize or it fails to honor a request, it
returns SSH_SMSG_FAILURE. It is expected that new message types might
be added to this phase in future.
The following messages are currently defined for this phase.
.IP SSH_CMSG_REQUEST_COMPRESSION
Requests that compression be enabled for this session. A
gzip-compatible compression level (1-9) is passed as an argument.
.IP SSH_CMSG_REQUEST_PTY
Requests that a pseudo terminal device be allocated for this session.
The user terminal type and terminal modes are supplied as arguments.
.IP SSH_CMSG_X11_REQUEST_FORWARDING
Requests forwarding of X11 connections from the remote machine to the
local machine over the secure channel. Causes an internet-domain
socket to be allocated and the DISPLAY variable to be set on the server.
X11 authentication data is automatically passed to the server, and the
client may implement spoofing of authentication data for added
security. The authentication data is passed as arguments.
.IP SSH_CMSG_PORT_FORWARD_REQUEST
Requests forwarding of a TCP/IP port on the server host over the
secure channel. What happens is that whenever a connection is made to
the port on the server, a connection will be made from the client end
to the specified host/port. Any user can forward unprivileged ports;
only the root can forward privileged ports (as determined by
authentication done earlier).
.IP SSH_CMSG_AGENT_REQUEST_FORWARDING
Requests forwarding of the connection to the authentication agent.
.IP SSH_CMSG_EXEC_SHELL
Starts a shell (command interpreter) for the user, and moves into
interactive session mode.
.IP SSH_CMSG_EXEC_CMD
Executes the given command (actually "<shell> -c <command>" or
equivalent) for the user, and moves into interactive session mode.
.RT
.ti 0
Interactive Session and Exchange of Data
During the interactive session, any data written by the shell or
command running on the server machine is forwarded to stdin or
stderr on the client machine, and any input available from stdin on
the client machine is forwarded to the program on the server machine.
All exchange is asynchronous; either side can send at any time, and
there are no acknowledgements (TCP/IP already provides reliable
transport, and the packet protocol protects against tampering or IP
spoofing).
When the client receives EOF from its standard input, it will send
SSH_CMSG_EOF; however, this in no way terminates the exchange. The
exchange terminates and interactive mode is left when the server sends
SSH_SMSG_EXITSTATUS to indicate that the client program has
terminated. Alternatively, either side may disconnect at any time by
sending SSH_MSG_DISCONNECT or closing the connection.
The server may send any of the following messages:
.IP SSH_SMSG_STDOUT_DATA
Data written to stdout by the program running on the server. The data
is passed as a string argument. The client writes this data to
stdout.
.IP SSH_SMSG_STDERR_DATA
Data written to stderr by the program running on the server. The data
is passed as a string argument. The client writes this data to
stderr. (Note that if the program is running on a tty, it is not
possible to separate stdout and stderr data, and all data will be sent
as stdout data.)
.IP SSH_SMSG_EXITSTATUS
Indicates that the shell or command has exited. Exit status is passed
as an integer argument. This message causes termination of the
interactive session.
.IP SSH_SMSG_AGENT_OPEN
Indicates that someone on the server side is requesting a connection
to the authentication agent. The server-side channel number is passed
as an argument. The client must respond with either
SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE.
.IP SSH_SMSG_X11_OPEN
Indicates that a connection has been made to the X11 socket on the
server side and should be forwarded to the real X server. An integer
argument indicates the channel number allocated for this connection on
the server side. The client should send back either
SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with
the same server side channel number.
.IP SSH_MSG_PORT_OPEN
Indicates that a connection has been made to a port on the server side
for which forwarding has been requested. Arguments are server side
channel number, host name to connect to, and port to connect to. The
client should send back either
SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with
the same server side channel number.
.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION
This is sent by the server to indicate that it has opened a connection
as requested in a previous message. The first argument indicates the
client side channel number, and the second argument is the channel number
that the server has allocated for this connection.
.IP SSH_MSG_CHANNEL_OPEN_FAILURE
This is sent by the server to indicate that it failed to open a
connection as requested in a previous message. The client-side
channel number is passed as an argument. The client will close the
descriptor associated with the channel and free the channel.
.IP SSH_MSG_CHANNEL_DATA
This packet contains data for a channel from the server. The first
argument is the client-side channel number, and the second argument (a
string) is the data.
.IP SSH_MSG_CHANNEL_CLOSE
This is sent by the server to indicate that whoever was in the other
end of the channel has closed it. The argument is the client side channel
number. The client will let all buffered data in the channel to
drain, and when ready, will close the socket, free the channel, and
send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the
channel.
.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
This is send by the server to indicate that a channel previously
closed by the client has now been closed on the server side as well.
The argument indicates the client channel number. The client frees
the channel.
.RT
The client may send any of the following messages:
.IP SSH_CMSG_STDIN_DATA
This is data to be sent as input to the program running on the server.
The data is passed as a string.
.IP SSH_CMSG_EOF
Indicates that the client has encountered EOF while reading standard
input. The server will allow any buffered input data to drain, and
will then close the input to the program.
.IP SSH_CMSG_WINDOW_SIZE
Indicates that window size on the client has been changed. The server
updates the window size of the tty and causes SIGWINCH to be sent to
the program. The new window size is passed as four integer arguments:
row, col, xpixel, ypixel.
.IP SSH_MSG_PORT_OPEN
Indicates that a connection has been made to a port on the client side
for which forwarding has been requested. Arguments are client side
channel number, host name to connect to, and port to connect to. The
server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or
SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number.
.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION
This is sent by the client to indicate that it has opened a connection
as requested in a previous message. The first argument indicates the
server side channel number, and the second argument is the channel
number that the client has allocated for this connection.
.IP SSH_MSG_CHANNEL_OPEN_FAILURE
This is sent by the client to indicate that it failed to open a
connection as requested in a previous message. The server side
channel number is passed as an argument. The server will close the
descriptor associated with the channel and free the channel.
.IP SSH_MSG_CHANNEL_DATA
This packet contains data for a channel from the client. The first
argument is the server side channel number, and the second argument (a
string) is the data.
.IP SSH_MSG_CHANNEL_CLOSE
This is sent by the client to indicate that whoever was in the other
end of the channel has closed it. The argument is the server channel
number. The server will allow buffered data to drain, and when ready,
will close the socket, free the channel, and send the client a
SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel.
.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
This is send by the client to indicate that a channel previously
closed by the server has now been closed on the client side as well.
The argument indicates the server channel number. The server frees
the channel.
.RT
Any unsupported messages during interactive mode cause the connection
to be terminated with SSH_MSG_DISCONNECT and an error message.
Compatible protocol upgrades should agree about any extensions during
the preparation phase or earlier.
.ti 0
Termination of the Connection
Normal termination of the connection is always initiated by the server
by sending SSH_SMSG_EXITSTATUS after the program has exited. The
client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION
and closes the socket; the server then closes the socket. There are
two purposes for the confirmation: some systems may lose previously
sent data when the socket is closed, and closing the client side first
causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not
consuming server resources.
If the program terminates due to a signal, the server will send
SSH_MSG_DISCONNECT with an appropriate message. If the connection is
closed, all file descriptors to the program will be closed and the
server will exit. If the program runs on a tty, the kernel sends it
the SIGHUP signal when the pty master side is closed.
.ti 0
Protocol Flags
Both the server and the client pass 32 bits of protocol flags to the
other side. The flags are intended for compatible protocol extension;
the server first announces which added capabilities it supports, and
the client then sends the capabilities that it supports.
The following flags are currently defined (the values are bit masks):
.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER"
This flag can only be sent by the client. It indicates that the X11
forwarding requests it sends will include the screen number.
.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN"
If both sides specify this flag, SSH_SMSG_X11_OPEN and
SSH_MSG_PORT_OPEN messages will contain an additional field containing
a description of the host at the other end of the connection.
.RT
.ti 0
Detailed Description of Packet Types and Formats
The supported packet types and the corresponding message numbers are
given in the following table. Messages with _MSG_ in their name may
be sent by either side. Messages with _CMSG_ are only sent by the
client, and messages with _SMSG_ only by the server.
A packet may contain additional data after the arguments specified
below. Any such data should be ignored by the receiver. However, it
is recommended that no such data be stored without good reason. (This
helps build compatible extensions.)
.IP "0 SSH_MSG_NONE"
This code is reserved. This message type is never sent.
.IP "1 SSH_MSG_DISCONNECT"
.TS
;
l l.
string Cause of disconnection
.TE
This message may be sent by either party at any time. It causes the
immediate disconnection of the connection. The message is intended to
be displayed to a human, and describes the reason for disconnection.
.IP "2 SSH_SMSG_PUBLIC_KEY"
.TS
;
l l.
8 bytes anti_spoofing_cookie
32-bit int server_key_bits
mp-int server_key_public_exponent
mp-int server_key_public_modulus
32-bit int host_key_bits
mp-int host_key_public_exponent
mp-int host_key_public_modulus
32-bit int protocol_flags
32-bit int supported_ciphers_mask
32-bit int supported_authentications_mask
.TE
Sent as the first message by the server. This message gives the
server's host key, server key, protocol flags (intended for compatible
protocol extension), supported_ciphers_mask (which is the
bitwise or of (1 << cipher_number), where << is the left shift
operator, for all supported ciphers), and
supported_authentications_mask (which is the bitwise or of (1 <<
authentication_type) for all supported authentication types). The
anti_spoofing_cookie is 64 random bytes, and must be sent back
verbatim by the client in its reply. It is used to make IP-spoofing
more difficult (encryption and host keys are the real defense against
spoofing).
.IP "3 SSH_CMSG_SESSION_KEY"
.TS
;
l l.
1 byte cipher_type (must be one of the supported values)
8 bytes anti_spoofing_cookie (must match data sent by the server)
mp-int double-encrypted session key
32-bit int protocol_flags
.TE
Sent by the client as the first message in the session. Selects the
cipher to use, and sends the encrypted session key to the server. The
anti_spoofing_cookie must be the same bytes that were sent by the
server. Protocol_flags is intended for negotiating compatible
protocol extensions.
.IP "4 SSH_CMSG_USER"
.TS
;
l l.
string user login name on server
.TE
Sent by the client to begin authentication. Specifies the user name
on the server to log in as. The server responds with SSH_SMSG_SUCCESS
if no authentication is needed for this user, or SSH_SMSG_FAILURE if
authentication is needed (or the user does not exist). [Note to the
implementator: the user name is of arbitrary size. The implementation
must be careful not to overflow internal buffers.]
.IP "5 SSH_CMSG_AUTH_RHOSTS"
.TS
;
l l.
string client-side user name
.TE
Requests authentication using /etc/hosts.equiv and .rhosts (or
equivalent mechanisms). This authentication method is normally
disabled in the server because it is not secure (but this is the
method used by rsh and rlogin). The server responds with
SSH_SMSG_SUCCESS if authentication was successful, and
SSH_SMSG_FAILURE if access was not granted. The server should check
that the client side port number is less than 1024 (a privileged
port), and immediately reject authentication if it is not. Supporting
this authentication method is optional. This method should normally
not be enabled in the server because it is not safe. (However, not
enabling this only helps if rlogind and rshd are disabled.)
.IP "6 SSH_CMSG_AUTH_RSA"
.TS
;
l l.
mp-int identity_public_modulus
.TE
Requests authentication using pure RSA authentication. The server
checks if the given key is permitted to log in, and if so, responds
with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with
SSH_SMSG_FAILURE. The client often tries several different keys in
sequence until one supported by the server is found. Authentication
is accepted if the client gives the correct response to the challenge.
The server is free to add other criteria for authentication, such as a
requirement that the connection must come from a certain host. Such
additions are not visible at the protocol level. Supporting this
authentication method is optional but recommended.
.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE"
.TS
;
l l.
mp-int encrypted challenge
.TE
Presents an RSA authentication challenge to the client. The challenge
is a 256-bit random value encrypted as described elsewhere in this
document. The client must decrypt the challenge using the RSA private
key, compute MD5 of the challenge plus session id, and send back the
resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE.
.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE"
.TS
;
l l.
16 bytes MD5 of decrypted challenge
.TE
This message is sent by the client in response to an RSA challenge.
The MD5 checksum is returned instead of the decrypted challenge to
deter known-plaintext attacks against the RSA key. The server
responds to this message with either SSH_SMSG_SUCCESS or
SSH_SMSG_FAILURE.
.IP "9 SSH_CMSG_AUTH_PASSWORD"
.TS
;
l l.
string plain text password
.TE
Requests password authentication using the given password. Note that
even though the password is plain text inside the packet, the whole
packet is normally encrypted by the packet layer. It would not be
possible for the client to perform password encryption/hashing,
because it cannot know which kind of encryption/hashing, if any, the
server uses. The server responds to this message with
SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE.
.IP "10 SSH_CMSG_REQUEST_PTY"
.TS
;
l l.
string TERM environment variable value (e.g. vt100)
32-bit int terminal height, rows (e.g., 24)
32-bit int terminal width, columns (e.g., 80)
32-bit int terminal width, pixels (0 if no graphics) (e.g., 480)
32-bit int terminal height, pixels (0 if no graphics) (e.g., 640)