summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c240
1 files changed, 233 insertions, 7 deletions
diff --git a/sshd.c b/sshd.c
index bb5685dc4..44782e397 100644
--- a/sshd.c
+++ b/sshd.c
@@ -8,10 +8,13 @@
8 * information to/from the application to the user client over an encrypted 8 * information to/from the application to the user client over an encrypted
9 * connection. This can also handle forwarding of X11, TCP/IP, and authentication 9 * connection. This can also handle forwarding of X11, TCP/IP, and authentication
10 * agent connections. 10 * agent connections.
11 *
12 * SSH2 implementation,
13 * Copyright (c) 2000 Markus Friedl. All rights reserved.
11 */ 14 */
12 15
13#include "includes.h" 16#include "includes.h"
14RCSID("$OpenBSD: sshd.c,v 1.97 2000/04/04 21:37:27 markus Exp $"); 17RCSID("$OpenBSD: sshd.c,v 1.99 2000/04/07 09:17:39 markus Exp $");
15 18
16#include "xmalloc.h" 19#include "xmalloc.h"
17#include "rsa.h" 20#include "rsa.h"
@@ -25,6 +28,7 @@ RCSID("$OpenBSD: sshd.c,v 1.97 2000/04/04 21:37:27 markus Exp $");
25#include "compat.h" 28#include "compat.h"
26#include "buffer.h" 29#include "buffer.h"
27 30
31#include "ssh2.h"
28#ifdef HAVE_OPENSSL 32#ifdef HAVE_OPENSSL
29# include <openssl/dh.h> 33# include <openssl/dh.h>
30# include <openssl/bn.h> 34# include <openssl/bn.h>
@@ -39,9 +43,12 @@ RCSID("$OpenBSD: sshd.c,v 1.97 2000/04/04 21:37:27 markus Exp $");
39# include <ssl/dsa.h> 43# include <ssl/dsa.h>
40# include <ssl/rsa.h> 44# include <ssl/rsa.h>
41#endif 45#endif
46#include "kex.h"
42#include "key.h" 47#include "key.h"
48#include "dsa.h"
43 49
44#include "auth.h" 50#include "auth.h"
51#include "myproposal.h"
45 52
46#ifdef LIBWRAP 53#ifdef LIBWRAP
47#include <tcpd.h> 54#include <tcpd.h>
@@ -70,6 +77,9 @@ int IPv4or6 = AF_INET;
70int IPv4or6 = AF_UNSPEC; 77int IPv4or6 = AF_UNSPEC;
71#endif 78#endif
72 79
80/* Flag indicating whether SSH2 is enabled */
81int allow_ssh2 = 0;
82
73/* 83/*
74 * Debug mode flag. This can be set on the command line. If debug 84 * Debug mode flag. This can be set on the command line. If debug
75 * mode is enabled, extra debugging output will be sent to the system 85 * mode is enabled, extra debugging output will be sent to the system
@@ -136,6 +146,7 @@ unsigned char session_id[16];
136 146
137/* Prototypes for various functions defined later in this file. */ 147/* Prototypes for various functions defined later in this file. */
138void do_ssh1_kex(); 148void do_ssh1_kex();
149void do_ssh2_kex();
139 150
140/* 151/*
141 * Close all listening sockets 152 * Close all listening sockets
@@ -255,6 +266,21 @@ key_regeneration_alarm(int sig)
255 errno = save_errno; 266 errno = save_errno;
256} 267}
257 268
269char *
270chop(char *s)
271{
272 char *t = s;
273 while (*t) {
274 if(*t == '\n' || *t == '\r') {
275 *t = '\0';
276 return s;
277 }
278 t++;
279 }
280 return s;
281
282}
283
258void 284void
259sshd_exchange_identification(int sock_in, int sock_out) 285sshd_exchange_identification(int sock_in, int sock_out)
260{ 286{
@@ -265,7 +291,9 @@ sshd_exchange_identification(int sock_in, int sock_out)
265 char remote_version[256]; /* Must be at least as big as buf. */ 291 char remote_version[256]; /* Must be at least as big as buf. */
266 292
267 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", 293 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
268 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); 294 allow_ssh2 ? 1 : PROTOCOL_MAJOR,
295 allow_ssh2 ? 99 : PROTOCOL_MINOR,
296 SSH_VERSION);
269 server_version_string = xstrdup(buf); 297 server_version_string = xstrdup(buf);
270 298
271 if (client_version_string == NULL) { 299 if (client_version_string == NULL) {
@@ -286,7 +314,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
286 buf[i] = '\n'; 314 buf[i] = '\n';
287 buf[i + 1] = 0; 315 buf[i + 1] = 0;
288 continue; 316 continue;
289 /*break; XXX eat \r */ 317 //break;
290 } 318 }
291 if (buf[i] == '\n') { 319 if (buf[i] == '\n') {
292 /* buf[i] == '\n' */ 320 /* buf[i] == '\n' */
@@ -315,6 +343,8 @@ sshd_exchange_identification(int sock_in, int sock_out)
315 debug("Client protocol version %d.%d; client software version %.100s", 343 debug("Client protocol version %d.%d; client software version %.100s",
316 remote_major, remote_minor, remote_version); 344 remote_major, remote_minor, remote_version);
317 345
346 compat_datafellows(remote_version);
347
318 switch(remote_major) { 348 switch(remote_major) {
319 case 1: 349 case 1:
320 if (remote_minor < 3) { 350 if (remote_minor < 3) {
@@ -324,7 +354,15 @@ sshd_exchange_identification(int sock_in, int sock_out)
324 /* note that this disables agent-forwarding */ 354 /* note that this disables agent-forwarding */
325 enable_compat13(); 355 enable_compat13();
326 } 356 }
327 break; 357 if (remote_minor != 99)
358 break;
359 /* FALLTHROUGH */
360 case 2:
361 if (allow_ssh2) {
362 enable_compat20();
363 break;
364 }
365 /* FALLTHROUGH */
328 default: 366 default:
329 s = "Protocol major versions differ.\n"; 367 s = "Protocol major versions differ.\n";
330 (void) atomicio(write, sock_out, s, strlen(s)); 368 (void) atomicio(write, sock_out, s, strlen(s));
@@ -335,6 +373,8 @@ sshd_exchange_identification(int sock_in, int sock_out)
335 fatal_cleanup(); 373 fatal_cleanup();
336 break; 374 break;
337 } 375 }
376 chop(server_version_string);
377 chop(client_version_string);
338} 378}
339 379
340/* 380/*
@@ -370,8 +410,11 @@ main(int ac, char **av)
370 initialize_server_options(&options); 410 initialize_server_options(&options);
371 411
372 /* Parse command-line arguments. */ 412 /* Parse command-line arguments. */
373 while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) { 413 while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ246")) != EOF) {
374 switch (opt) { 414 switch (opt) {
415 case '2':
416 allow_ssh2 = 1;
417 break;
375 case '4': 418 case '4':
376 IPv4or6 = AF_INET; 419 IPv4or6 = AF_INET;
377 break; 420 break;
@@ -837,9 +880,14 @@ main(int ac, char **av)
837 packet_set_nonblocking(); 880 packet_set_nonblocking();
838 881
839 /* perform the key exchange */ 882 /* perform the key exchange */
840 do_ssh1_kex();
841 /* authenticate user and start session */ 883 /* authenticate user and start session */
842 do_authentication(); 884 if (compat20) {
885 do_ssh2_kex();
886 do_authentication2();
887 } else {
888 do_ssh1_kex();
889 do_authentication();
890 }
843 891
844#ifdef KRB4 892#ifdef KRB4
845 /* Cleanup user's ticket cache file. */ 893 /* Cleanup user's ticket cache file. */
@@ -1049,3 +1097,181 @@ do_ssh1_kex()
1049 packet_send(); 1097 packet_send();
1050 packet_write_wait(); 1098 packet_write_wait();
1051} 1099}
1100
1101/*
1102 * SSH2 key exchange: diffie-hellman-group1-sha1
1103 */
1104void
1105do_ssh2_kex()
1106{
1107 Buffer *server_kexinit;
1108 Buffer *client_kexinit;
1109 int payload_len, dlen;
1110 int slen;
1111 unsigned int klen, kout;
1112 char *ptr;
1113 unsigned char *signature = NULL;
1114 unsigned char *server_host_key_blob = NULL;
1115 unsigned int sbloblen;
1116 DH *dh;
1117 BIGNUM *dh_client_pub = 0;
1118 BIGNUM *shared_secret = 0;
1119 int i;
1120 unsigned char *kbuf;
1121 unsigned char *hash;
1122 Kex *kex;
1123 Key *server_host_key;
1124 char *cprop[PROPOSAL_MAX];
1125 char *sprop[PROPOSAL_MAX];
1126
1127/* KEXINIT */
1128
1129 debug("Sending KEX init.");
1130
1131 for (i = 0; i < PROPOSAL_MAX; i++)
1132 sprop[i] = xstrdup(myproposal[i]);
1133 server_kexinit = kex_init(sprop);
1134 packet_start(SSH2_MSG_KEXINIT);
1135 packet_put_raw(buffer_ptr(server_kexinit), buffer_len(server_kexinit));
1136 packet_send();
1137 packet_write_wait();
1138
1139 debug("done");
1140
1141 packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);
1142
1143 /*
1144 * save raw KEXINIT payload in buffer. this is used during
1145 * computation of the session_id and the session keys.
1146 */
1147 client_kexinit = xmalloc(sizeof(*client_kexinit));
1148 buffer_init(client_kexinit);
1149 ptr = packet_get_raw(&payload_len);
1150 buffer_append(client_kexinit, ptr, payload_len);
1151
1152 /* skip cookie */
1153 for (i = 0; i < 16; i++)
1154 (void) packet_get_char();
1155 /* save kex init proposal strings */
1156 for (i = 0; i < PROPOSAL_MAX; i++) {
1157 cprop[i] = packet_get_string(NULL);
1158 debug("got kexinit string: %s", cprop[i]);
1159 }
1160
1161 i = (int) packet_get_char();
1162 debug("first kex follow == %d", i);
1163 i = packet_get_int();
1164 debug("reserved == %d", i);
1165
1166 debug("done read kexinit");
1167 kex = kex_choose_conf(cprop, sprop, 1);
1168
1169/* KEXDH */
1170
1171 debug("Wait SSH2_MSG_KEXDH_INIT.");
1172 packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);
1173
1174 /* key, cert */
1175 dh_client_pub = BN_new();
1176 if (dh_client_pub == NULL)
1177 fatal("dh_client_pub == NULL");
1178 packet_get_bignum2(dh_client_pub, &dlen);
1179
1180#ifdef DEBUG_KEXDH
1181 fprintf(stderr, "\ndh_client_pub= ");
1182 bignum_print(dh_client_pub);
1183 fprintf(stderr, "\n");
1184 debug("bits %d", BN_num_bits(dh_client_pub));
1185#endif
1186
1187 /* generate DH key */
1188 dh = new_dh_group1(); /* XXX depends on 'kex' */
1189
1190#ifdef DEBUG_KEXDH
1191 fprintf(stderr, "\np= ");
1192 bignum_print(dh->p);
1193 fprintf(stderr, "\ng= ");
1194 bignum_print(dh->g);
1195 fprintf(stderr, "\npub= ");
1196 bignum_print(dh->pub_key);
1197 fprintf(stderr, "\n");
1198#endif
1199
1200 klen = DH_size(dh);
1201 kbuf = xmalloc(klen);
1202 kout = DH_compute_key(kbuf, dh_client_pub, dh);
1203
1204#ifdef DEBUG_KEXDH
1205 debug("shared secret: len %d/%d", klen, kout);
1206 fprintf(stderr, "shared secret == ");
1207 for (i = 0; i< kout; i++)
1208 fprintf(stderr, "%02x", (kbuf[i])&0xff);
1209 fprintf(stderr, "\n");
1210#endif
1211 shared_secret = BN_new();
1212
1213 BN_bin2bn(kbuf, kout, shared_secret);
1214 memset(kbuf, 0, klen);
1215 xfree(kbuf);
1216
1217 server_host_key = dsa_get_serverkey(options.dsa_key_file);
1218 dsa_make_serverkey_blob(server_host_key, &server_host_key_blob, &sbloblen);
1219
1220 /* calc H */ /* XXX depends on 'kex' */
1221 hash = kex_hash(
1222 client_version_string,
1223 server_version_string,
1224 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
1225 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
1226 (char *)server_host_key_blob, sbloblen,
1227 dh_client_pub,
1228 dh->pub_key,
1229 shared_secret
1230 );
1231 buffer_free(client_kexinit);
1232 buffer_free(server_kexinit);
1233 xfree(client_kexinit);
1234 xfree(server_kexinit);
1235#ifdef DEBUG_KEXDH
1236 fprintf(stderr, "hash == ");
1237 for (i = 0; i< 20; i++)
1238 fprintf(stderr, "%02x", (hash[i])&0xff);
1239 fprintf(stderr, "\n");
1240#endif
1241 /* sign H */
1242 dsa_sign(server_host_key, &signature, &slen, hash, 20);
1243 /* hashlen depends on KEX */
1244 key_free(server_host_key);
1245
1246 /* send server hostkey, DH pubkey 'f' and singed H */
1247 packet_start(SSH2_MSG_KEXDH_REPLY);
1248 packet_put_string((char *)server_host_key_blob, sbloblen);
1249 packet_put_bignum2(dh->pub_key); // f
1250 packet_put_string((char *)signature, slen);
1251 packet_send();
1252 packet_write_wait();
1253
1254 kex_derive_keys(kex, hash, shared_secret);
1255 packet_set_kex(kex);
1256
1257 /* have keys, free DH */
1258 DH_free(dh);
1259
1260 debug("send SSH2_MSG_NEWKEYS.");
1261 packet_start(SSH2_MSG_NEWKEYS);
1262 packet_send();
1263 packet_write_wait();
1264 debug("done: send SSH2_MSG_NEWKEYS.");
1265
1266 debug("Wait SSH2_MSG_NEWKEYS.");
1267 packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
1268 debug("GOT SSH2_MSG_NEWKEYS.");
1269
1270 /* send 1st encrypted/maced/compressed message */
1271 packet_start(SSH2_MSG_IGNORE);
1272 packet_put_cstring("markus");
1273 packet_send();
1274 packet_write_wait();
1275
1276 debug("done: KEX2.");
1277}