1 /*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 #include "libwebsockets.h"
26 #include "lws-ssh.h"
27
28 #include <string.h>
29 #include <stdlib.h>
30
sshd_zalloc(size_t s)31 void *sshd_zalloc(size_t s)
32 {
33 void *p = malloc(s);
34
35 if (p)
36 memset(p, 0, s);
37
38 return p;
39 }
40
41 uint32_t
lws_g32(uint8_t ** p)42 lws_g32(uint8_t **p)
43 {
44 uint32_t v = 0;
45
46 v = (v << 8) | *((*p)++);
47 v = (v << 8) | *((*p)++);
48 v = (v << 8) | *((*p)++);
49 v = (v << 8) | *((*p)++);
50
51 return v;
52 }
53
54 uint32_t
lws_p32(uint8_t * p,uint32_t v)55 lws_p32(uint8_t *p, uint32_t v)
56 {
57 *p++ = v >> 24;
58 *p++ = v >> 16;
59 *p++ = v >> 8;
60 *p++ = v;
61
62 return v;
63 }
64
65 int
lws_cstr(uint8_t ** p,const char * s,uint32_t max)66 lws_cstr(uint8_t **p, const char *s, uint32_t max)
67 {
68 uint32_t n = (uint32_t)strlen(s);
69
70 if (n > max)
71 return 1;
72
73 lws_p32(*p, n);
74 *p += 4;
75 strcpy((char *)(*p), s);
76 *p += n;
77
78 return 0;
79 }
80
81 int
lws_buf(uint8_t ** p,void * s,uint32_t len)82 lws_buf(uint8_t **p, void *s, uint32_t len)
83 {
84 lws_p32(*p, len);
85 *p += 4;
86 memcpy((char *)(*p), s, len);
87 *p += len;
88
89 return 0;
90 }
91
92 void
write_task(struct per_session_data__sshd * pss,struct lws_ssh_channel * ch,int task)93 write_task(struct per_session_data__sshd *pss, struct lws_ssh_channel *ch,
94 int task)
95 {
96 pss->write_task[pss->wt_head] = task;
97 pss->write_channel[pss->wt_head] = ch;
98 pss->wt_head = (pss->wt_head + 1) & 7;
99 lws_callback_on_writable(pss->wsi);
100 }
101
102 void
write_task_insert(struct per_session_data__sshd * pss,struct lws_ssh_channel * ch,int task)103 write_task_insert(struct per_session_data__sshd *pss, struct lws_ssh_channel *ch,
104 int task)
105 {
106 pss->wt_tail = (pss->wt_tail - 1) & 7;
107 pss->write_task[pss->wt_tail] = task;
108 pss->write_channel[pss->wt_tail] = ch;
109 lws_callback_on_writable(pss->wsi);
110 }
111
112
113 void
lws_pad_set_length(struct per_session_data__sshd * pss,void * start,uint8_t ** p,struct lws_ssh_keys * keys)114 lws_pad_set_length(struct per_session_data__sshd *pss, void *start, uint8_t **p,
115 struct lws_ssh_keys *keys)
116 {
117 uint32_t len = lws_ptr_diff(*p, start);
118 uint8_t padc = 4, *bs = start;
119
120 if (keys->full_length)
121 len -= 4;
122
123 if ((len + padc) & (keys->padding_alignment - 1))
124 padc += keys->padding_alignment -
125 ((len + padc) & (keys->padding_alignment - 1));
126
127 bs[4] = padc;
128 len += padc;
129
130 if (!keys->valid) /* no crypto = pad with 00 */
131 while (padc--)
132 *((*p)++) = 0;
133 else { /* crypto active = pad with random */
134 lws_get_random(pss->vhd->context, *p, padc);
135 (*p) += padc;
136 }
137 if (keys->full_length)
138 len += 4;
139
140 lws_p32(start, len - 4);
141 }
142
143 static uint32_t
offer(struct per_session_data__sshd * pss,uint8_t * p,uint32_t len,int first,int * payload_len)144 offer(struct per_session_data__sshd *pss, uint8_t *p, uint32_t len, int first,
145 int *payload_len)
146 {
147 uint8_t *op = p, *lp, *end = p + len - 1;
148 int n, padc = 4, keylen;
149 char keyt[32];
150 uint8_t keybuf[256];
151
152 keylen = (int)get_gen_server_key_25519(pss, keybuf, (int)sizeof(keybuf));
153 if (!keylen) {
154 lwsl_notice("get_gen_server_key failed\n");
155 return 1;
156 }
157 lwsl_info("keylen %d\n", keylen);
158 n = ed25519_key_parse(keybuf, keylen,
159 keyt, sizeof(keyt), NULL, NULL);
160 if (n) {
161 lwsl_notice("unable to parse server key: %d\n", n);
162 return 1;
163 }
164
165 /*
166 * byte SSH_MSG_KEXINIT
167 * byte[16] cookie (random bytes)
168 * name-list kex_algorithms
169 * name-list server_host_key_algorithms
170 * name-list encryption_algorithms_client_to_server
171 * name-list encryption_algorithms_server_to_client
172 * name-list mac_algorithms_client_to_server
173 * name-list mac_algorithms_server_to_client
174 * name-list compression_algorithms_client_to_server
175 * name-list compression_algorithms_server_to_client
176 * name-list langua->es_client_to_server
177 * name-list langua->es_server_to_client
178 * boolean first_kex_packet_follows
179 * uint32 0 (reserved for future extension)
180 */
181
182 p += 5; /* msg len + padding */
183
184 *p++ = SSH_MSG_KEXINIT;
185 lws_get_random(pss->vhd->context, p, 16);
186 p += 16;
187
188 /* KEX algorithms */
189
190 lp = p;
191 p += 4;
192 n = lws_snprintf((char *)p, end - p, "curve25519-sha256@libssh.org");
193 p += lws_p32(lp, n);
194
195 /* Server Host Key Algorithms */
196
197 lp = p;
198 p += 4;
199 n = lws_snprintf((char *)p, end - p, "%s", keyt);
200 p += lws_p32(lp, n);
201
202 /* Encryption Algorithms: C -> S */
203
204 lp = p;
205 p += 4;
206 // n = lws_snprintf((char *)p, end - p, "aes256-gcm@openssh.com");
207 n = lws_snprintf((char *)p, end - p, "chacha20-poly1305@openssh.com");
208 p += lws_p32(lp, n);
209
210 /* Encryption Algorithms: S -> C */
211
212 lp = p;
213 p += 4;
214 // n = lws_snprintf((char *)p, end - p, "aes256-gcm@openssh.com");
215 n = lws_snprintf((char *)p, end - p, "chacha20-poly1305@openssh.com");
216 p += lws_p32(lp, n);
217
218 /* MAC Algorithms: C -> S */
219
220 lp = p;
221 p += 4;
222 /* bogus: chacha20 does not use MACs, but 'none' is not offered */
223 n = lws_snprintf((char *)p, end - p, "hmac-sha2-256");
224 p += lws_p32(lp, n);
225
226 /* MAC Algorithms: S -> C */
227
228 lp = p;
229 p += 4;
230 /* bogus: chacha20 does not use MACs, but 'none' is not offered */
231 n = lws_snprintf((char *)p, end - p, "hmac-sha2-256");
232 p += lws_p32(lp, n);
233
234 /* Compression Algorithms: C -> S */
235
236 lp = p;
237 p += 4;
238 n = lws_snprintf((char *)p, end - p, "none");
239 p += lws_p32(lp, n);
240
241 /* Compression Algorithms: S -> C */
242
243 lp = p;
244 p += 4;
245 n = lws_snprintf((char *)p, end - p, "none");
246 p += lws_p32(lp, n);
247
248 if (p - op < 13 + padc + 8)
249 return 0;
250
251 /* Languages: C -> S */
252
253 *p++ = 0;
254 *p++ = 0;
255 *p++ = 0;
256 *p++ = 0;
257
258 /* Languages: S -> C */
259
260 *p++ = 0;
261 *p++ = 0;
262 *p++ = 0;
263 *p++ = 0;
264
265 /* First KEX packet coming */
266
267 *p++ = !!first;
268
269 /* Reserved */
270
271 *p++ = 0;
272 *p++ = 0;
273 *p++ = 0;
274 *p++ = 0;
275
276 len = lws_ptr_diff(p, op);
277 if (payload_len)
278 /* starts at buf + 5 and excludes padding */
279 *payload_len = len - 5;
280
281 /* we must give at least 4 bytes of 00 padding */
282
283 if ((len + padc) & 7)
284 padc += 8 - ((len + padc) & 7);
285
286 op[4] = padc;
287 len += padc;
288
289 while (padc--)
290 *p++ = 0;
291
292 /* recorded length does not include the uint32_t len itself */
293 lws_p32(op, len - 4);
294
295 return len;
296 }
297
298 static int
handle_name(struct per_session_data__sshd * pss)299 handle_name(struct per_session_data__sshd *pss)
300 {
301 struct lws_kex *kex = pss->kex;
302 char keyt[32];
303 uint8_t keybuf[256];
304 int n = 0, len;
305
306 switch (pss->parser_state) {
307 case SSH_KEX_NL_KEX_ALGS:
308 if (!strcmp(pss->name, "curve25519-sha256@libssh.org"))
309 kex->match_bitfield |= 1;
310 break;
311 case SSH_KEX_NL_SHK_ALGS:
312 len = (int)get_gen_server_key_25519(pss, keybuf, (int)sizeof(keybuf));
313 if (!len)
314 break;
315 if (ed25519_key_parse(keybuf, len,
316 keyt, sizeof(keyt),
317 NULL, NULL)) {
318 lwsl_err("Unable to parse host key %d\n", n);
319 } else {
320 if (!strcmp(pss->name, keyt)) {
321 kex->match_bitfield |= 2;
322 break;
323 }
324 }
325 break;
326 case SSH_KEX_NL_EACTS_ALGS:
327 if (!strcmp(pss->name, "chacha20-poly1305@openssh.com"))
328 kex->match_bitfield |= 4;
329 break;
330 case SSH_KEX_NL_EASTC_ALGS:
331 if (!strcmp(pss->name, "chacha20-poly1305@openssh.com"))
332 kex->match_bitfield |= 8;
333 break;
334 case SSH_KEX_NL_MACTS_ALGS:
335 if (!strcmp(pss->name, "hmac-sha2-256"))
336 kex->match_bitfield |= 16;
337 break;
338 case SSH_KEX_NL_MASTC_ALGS:
339 if (!strcmp(pss->name, "hmac-sha2-256"))
340 kex->match_bitfield |= 32;
341 break;
342 case SSH_KEX_NL_CACTS_ALGS:
343 if (!strcmp(pss->name, "none"))
344 kex->match_bitfield |= 64;
345 break;
346 case SSH_KEX_NL_CASTC_ALGS:
347 if (!strcmp(pss->name, "none"))
348 kex->match_bitfield |= 128;
349 break;
350 case SSH_KEX_NL_LCTS_ALGS:
351 case SSH_KEX_NL_LSTC_ALGS:
352 break;
353 default:
354 break;
355 }
356
357 return 0;
358 }
359
360
361 static int
lws_kex_create(struct per_session_data__sshd * pss)362 lws_kex_create(struct per_session_data__sshd *pss)
363 {
364 pss->kex = sshd_zalloc(sizeof(struct lws_kex));
365 lwsl_info("%s\n", __func__);
366 return !pss->kex;
367 }
368
369 static void
lws_kex_destroy(struct per_session_data__sshd * pss)370 lws_kex_destroy(struct per_session_data__sshd *pss)
371 {
372 if (!pss->kex)
373 return;
374
375 lwsl_info("Destroying KEX\n");
376
377 if (pss->kex->I_C) {
378 free(pss->kex->I_C);
379 pss->kex->I_C = NULL;
380 }
381 if (pss->kex->I_S) {
382 free(pss->kex->I_S);
383 pss->kex->I_S = NULL;
384 }
385
386 lws_explicit_bzero(pss->kex, sizeof(*pss->kex));
387 free(pss->kex);
388 pss->kex = NULL;
389 }
390
391 static void
ssh_free(void * p)392 ssh_free(void *p)
393 {
394 if (!p)
395 return;
396
397 lwsl_debug("%s: FREE %p\n", __func__, p);
398 free(p);
399 }
400
401 #define ssh_free_set_NULL(x) if (x) { ssh_free(x); (x) = NULL; }
402
403 static void
lws_ua_destroy(struct per_session_data__sshd * pss)404 lws_ua_destroy(struct per_session_data__sshd *pss)
405 {
406 if (!pss->ua)
407 return;
408
409 lwsl_info("%s\n", __func__);
410
411 if (pss->ua->username)
412 ssh_free(pss->ua->username);
413 if (pss->ua->service)
414 ssh_free(pss->ua->service);
415 if (pss->ua->alg)
416 ssh_free(pss->ua->alg);
417 if (pss->ua->pubkey)
418 ssh_free(pss->ua->pubkey);
419 if (pss->ua->sig) {
420 lws_explicit_bzero(pss->ua->sig, pss->ua->sig_len);
421 ssh_free(pss->ua->sig);
422 }
423
424 lws_explicit_bzero(pss->ua, sizeof(*pss->ua));
425 free(pss->ua);
426 pss->ua = NULL;
427 }
428
429
430 static int
rsa_hash_alg_from_ident(const char * ident)431 rsa_hash_alg_from_ident(const char *ident)
432 {
433 if (strcmp(ident, "ssh-rsa") == 0 ||
434 strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 0)
435 return LWS_GENHASH_TYPE_SHA1;
436 if (strcmp(ident, "rsa-sha2-256") == 0)
437 return LWS_GENHASH_TYPE_SHA256;
438 if (strcmp(ident, "rsa-sha2-512") == 0)
439 return LWS_GENHASH_TYPE_SHA512;
440
441 return -1;
442 }
443
444 static void
state_get_string_alloc(struct per_session_data__sshd * pss,int next)445 state_get_string_alloc(struct per_session_data__sshd *pss, int next)
446 {
447 pss->parser_state = SSHS_GET_STRING_LEN_ALLOC;
448 pss->state_after_string = next;
449 }
450
451 static void
state_get_string(struct per_session_data__sshd * pss,int next)452 state_get_string(struct per_session_data__sshd *pss, int next)
453 {
454 pss->parser_state = SSHS_GET_STRING_LEN;
455 pss->state_after_string = next;
456 }
457
458 static void
state_get_u32(struct per_session_data__sshd * pss,int next)459 state_get_u32(struct per_session_data__sshd *pss, int next)
460 {
461 pss->parser_state = SSHS_GET_U32;
462 pss->state_after_string = next;
463 }
464
465 static struct lws_ssh_channel *
ssh_get_server_ch(struct per_session_data__sshd * pss,uint32_t chi)466 ssh_get_server_ch(struct per_session_data__sshd *pss, uint32_t chi)
467 {
468 struct lws_ssh_channel *ch = pss->ch_list;
469
470 while (ch) {
471 if (ch->server_ch == chi)
472 return ch;
473 ch = ch->next;
474 }
475
476 return NULL;
477 }
478
479 #if 0
480 static struct lws_ssh_channel *
481 ssh_get_peer_ch(struct per_session_data__sshd *pss, uint32_t chi)
482 {
483 struct lws_ssh_channel *ch = pss->ch_list;
484
485 while (ch) {
486 if (ch->sender_ch == chi)
487 return ch;
488 ch = ch->next;
489 }
490
491 return NULL;
492 }
493 #endif
494
495 static void
ssh_destroy_channel(struct per_session_data__sshd * pss,struct lws_ssh_channel * ch)496 ssh_destroy_channel(struct per_session_data__sshd *pss,
497 struct lws_ssh_channel *ch)
498 {
499 lws_start_foreach_llp(struct lws_ssh_channel **, ppch, pss->ch_list) {
500 if (*ppch == ch) {
501 lwsl_info("Deleting ch %p\n", ch);
502 if (pss->vhd && pss->vhd->ops &&
503 pss->vhd->ops->channel_destroy)
504 pss->vhd->ops->channel_destroy(ch->priv);
505 *ppch = ch->next;
506 if (ch->sub)
507 free(ch->sub);
508 free(ch);
509
510 return;
511 }
512 } lws_end_foreach_llp(ppch, next);
513
514 lwsl_notice("Failed to delete ch\n");
515 }
516
517 static void
lws_ssh_exec_finish(void * finish_handle,int retcode)518 lws_ssh_exec_finish(void *finish_handle, int retcode)
519 {
520 struct lws_ssh_channel *ch = (struct lws_ssh_channel *)finish_handle;
521 struct per_session_data__sshd *pss = ch->pss;
522
523 ch->retcode = retcode;
524 write_task(pss, ch, SSH_WT_EXIT_STATUS);
525 ch->scheduled_close = 1;
526 write_task(pss, ch, SSH_WT_CH_CLOSE);
527 }
528
529 static int
lws_ssh_parse_plaintext(struct per_session_data__sshd * pss,uint8_t * p,size_t len)530 lws_ssh_parse_plaintext(struct per_session_data__sshd *pss, uint8_t *p, size_t len)
531 {
532 struct lws_gencrypto_keyelem e[LWS_GENCRYPTO_RSA_KEYEL_COUNT];
533 struct lws_genrsa_ctx ctx;
534 struct lws_ssh_channel *ch;
535 struct lws_subprotocol_scp *scp;
536 uint8_t *pp, *ps, hash[64], *otmp;
537 uint32_t m;
538 int n;
539
540 while (len --) {
541 again:
542 switch(pss->parser_state) {
543 case SSH_INITIALIZE_TRANSIENT:
544 pss->parser_state = SSHS_IDSTRING;
545 pss->ctr = 0;
546 pss->copy_to_I_C = 0;
547
548 /* fallthru */
549 case SSHS_IDSTRING:
550 if (*p == 0x0d) {
551 pss->V_C[pss->npos] = '\0';
552 pss->npos = 0;
553 lwsl_info("peer id: %s\n", pss->V_C);
554 p++;
555 pss->parser_state = SSHS_IDSTRING_CR;
556 break;
557 }
558 if (pss->npos < sizeof(pss->V_C) - 1)
559 pss->V_C[pss->npos++] = *p;
560 p++;
561 break;
562
563 case SSHS_IDSTRING_CR:
564 if (*p++ != 0x0a) {
565 lwsl_notice("mangled id string\n");
566 return 1;
567 }
568 pss->ssh_sequence_ctr_cts = 0;
569 pss->parser_state = SSHS_MSG_LEN;
570 break;
571
572 case SSHS_MSG_LEN:
573 pss->msg_len = (pss->msg_len << 8) | *p++;
574 if (++pss->ctr != 4)
575 break;
576
577 if (pss->active_keys_cts.valid) {
578 uint8_t b[4];
579
580 POKE_U32(b, pss->msg_len);
581 pss->msg_len = lws_chachapoly_get_length(
582 &pss->active_keys_cts,
583 pss->ssh_sequence_ctr_cts, b);
584 } else
585 pss->ssh_sequence_ctr_cts++;
586
587 lwsl_info("msg len %d\n", pss->msg_len);
588
589 pss->parser_state = SSHS_MSG_PADDING;
590 pss->ctr = 0;
591 pss->pos = 4;
592 if (pss->msg_len < 2 + 4) {
593 lwsl_notice("illegal msg size\n");
594 goto bail;
595 }
596 break;
597
598 case SSHS_MSG_PADDING:
599 pss->msg_padding = *p++;
600 pss->parser_state = SSHS_MSG_ID;
601 break;
602
603 case SSHS_MSG_ID:
604 pss->msg_id = *p++;
605 pss->ctr = 0;
606 switch (pss->msg_id) {
607 case SSH_MSG_DISCONNECT:
608 /*
609 * byte SSH_MSG_DISCONNECT
610 * uint32 reason code
611 * string description in ISO-10646
612 * UTF-8 encoding [RFC3629]
613 * string language tag [RFC3066]
614 */
615 lwsl_notice("SSH_MSG_DISCONNECT\n");
616 state_get_u32(pss, SSHS_NVC_DISCONNECT_REASON);
617 break;
618 case SSH_MSG_IGNORE:
619 lwsl_notice("SSH_MSG_IGNORE\n");
620 break;
621 case SSH_MSG_UNIMPLEMENTED:
622 lwsl_notice("SSH_MSG_UNIMPLEMENTED\n");
623 break;
624 case SSH_MSG_DEBUG:
625 lwsl_notice("SSH_MSG_DEBUG\n");
626 break;
627 case SSH_MSG_SERVICE_REQUEST:
628 lwsl_info("SSH_MSG_SERVICE_REQUEST\n");
629 /* payload is a string */
630 state_get_string(pss, SSHS_DO_SERVICE_REQUEST);
631 break;
632 case SSH_MSG_SERVICE_ACCEPT:
633 lwsl_notice("SSH_MSG_ACCEPT\n");
634 break;
635
636 case SSH_MSG_KEXINIT:
637 if (pss->kex_state !=
638 KEX_STATE_EXPECTING_CLIENT_OFFER) {
639 pss->parser_state = SSH_KEX_STATE_SKIP;
640 break;
641 }
642 if (!pss->kex) {
643 lwsl_notice("%s: SSH_MSG_KEXINIT: NULL pss->kex\n", __func__);
644 goto bail;
645 }
646 pss->parser_state = SSH_KEX_STATE_COOKIE;
647 pss->kex->I_C_payload_len = 0;
648 pss->kex->I_C_alloc_len = pss->msg_len;
649 pss->kex->I_C = sshd_zalloc(pss->kex->I_C_alloc_len);
650 if (!pss->kex->I_C) {
651 lwsl_notice("OOM 3\n");
652 goto bail;
653 }
654 pss->kex->I_C[pss->kex->I_C_payload_len++] =
655 pss->msg_id;
656 pss->copy_to_I_C = 1;
657 break;
658 case SSH_MSG_KEX_ECDH_INIT:
659 pss->parser_state = SSH_KEX_STATE_ECDH_KEYLEN;
660 break;
661
662 case SSH_MSG_NEWKEYS:
663 if (pss->kex_state !=
664 KEX_STATE_REPLIED_TO_OFFER &&
665 pss->kex_state !=
666 KEX_STATE_CRYPTO_INITIALIZED) {
667 lwsl_notice("unexpected newkeys\n");
668
669 goto bail;
670 }
671 /*
672 * it means we should now use the keys we
673 * agreed on
674 */
675 lwsl_info("Activating CTS keys\n");
676 pss->active_keys_cts = pss->kex->keys_next_cts;
677 if (lws_chacha_activate(&pss->active_keys_cts))
678 goto bail;
679
680 pss->kex->newkeys |= 2;
681 if (pss->kex->newkeys == 3)
682 lws_kex_destroy(pss);
683
684 if (pss->msg_padding) {
685 pss->copy_to_I_C = 0;
686 pss->parser_state =
687 SSHS_MSG_EAT_PADDING;
688 break;
689 } else {
690 pss->parser_state = SSHS_MSG_LEN;
691 }
692 break;
693
694 case SSH_MSG_USERAUTH_REQUEST:
695 /*
696 * byte SSH_MSG_USERAUTH_REQUEST
697 * string user name in UTF-8
698 * encoding [RFC3629]
699 * string service name in US-ASCII
700 * string "publickey"
701 * boolean FALSE
702 * string public key alg
703 * string public key blob
704 */
705 lwsl_info("SSH_MSG_USERAUTH_REQUEST\n");
706 if (pss->ua) {
707 lwsl_notice("pss->ua overwrite\n");
708
709 goto bail;
710 }
711
712 pss->ua = sshd_zalloc(sizeof(*pss->ua));
713 if (!pss->ua)
714 goto bail;
715
716 state_get_string_alloc(pss, SSHS_DO_UAR_SVC);
717 /* username is destroyed with userauth struct */
718 if (!pss->sent_banner) {
719 if (pss->vhd->ops->banner)
720 write_task(pss, NULL,
721 SSH_WT_UA_BANNER);
722 pss->sent_banner = 1;
723 }
724 break;
725 case SSH_MSG_USERAUTH_FAILURE:
726 goto bail;
727 case SSH_MSG_USERAUTH_SUCCESS:
728 goto bail;
729 case SSH_MSG_USERAUTH_BANNER:
730 goto bail;
731
732 case SSH_MSG_CHANNEL_OPEN:
733 state_get_string(pss, SSHS_NVC_CHOPEN_TYPE);
734 break;
735
736 case SSH_MSG_CHANNEL_REQUEST:
737 /* RFC4254
738 *
739 * byte SSH_MSG_CHANNEL_REQUEST
740 * uint32 recipient channel
741 * string "pty-req"
742 * boolean want_reply
743 * string TERM environment variable value
744 * (e.g., vt100)
745 * uint32 terminal width, characters
746 * (e.g., 80)
747 * uint32 terminal height, rows (e.g., 24)
748 * uint32 terminal width, px (e.g., 640)
749 * uint32 terminal height, px (e.g., 480)
750 * string encoded terminal modes
751 */
752 state_get_u32(pss, SSHS_NVC_CHRQ_RECIP);
753 break;
754
755 case SSH_MSG_CHANNEL_EOF:
756 /* RFC4254
757 * When a party will no longer send more data
758 * to a channel, it SHOULD send
759 * SSH_MSG_CHANNEL_EOF.
760 *
761 * byte SSH_MSG_CHANNEL_EOF
762 * uint32 recipient channel
763 */
764 state_get_u32(pss, SSHS_NVC_CH_EOF);
765 break;
766
767 case SSH_MSG_CHANNEL_CLOSE:
768 /* RFC4254
769 *
770 * byte SSH_MSG_CHANNEL_CLOSE
771 * uint32 recipient channel
772 *
773 * This message does not consume window space
774 * and can be sent even if no window space is
775 * available.
776 *
777 * It is RECOMMENDED that all data sent before
778 * this message be delivered to the actual
779 * destination, if possible.
780 */
781 state_get_u32(pss, SSHS_NVC_CH_CLOSE);
782 break;
783
784 case SSH_MSG_CHANNEL_DATA:
785 /* RFC4254
786 *
787 * byte SSH_MSG_CHANNEL_DATA
788 * uint32 recipient channel
789 * string data
790 */
791 state_get_u32(pss, SSHS_NVC_CD_RECIP);
792 break;
793
794 case SSH_MSG_CHANNEL_WINDOW_ADJUST:
795 /* RFC452
796 *
797 * byte SSH_MSG_CHANNEL_WINDOW_ADJUST
798 * uint32 recipient channel
799 * uint32 bytes to add
800 */
801 if (!pss->ch_list)
802 goto bail;
803
804 state_get_u32(pss, SSHS_NVC_WA_RECIP);
805 break;
806 default:
807 lwsl_notice("unk msg_id %d\n", pss->msg_id);
808
809 goto bail;
810 }
811 break;
812
813 case SSH_KEX_STATE_COOKIE:
814 if (pss->msg_len < 16 + 1 + 1 + (10 * 4) + 5) {
815 lwsl_notice("sanity: kex length failed\n");
816 goto bail;
817 }
818 pss->kex->kex_cookie[pss->ctr++] = *p++;
819 if (pss->ctr != sizeof(pss->kex->kex_cookie))
820 break;
821 pss->parser_state = SSH_KEX_NL_KEX_ALGS_LEN;
822 pss->ctr = 0;
823 break;
824 case SSH_KEX_NL_KEX_ALGS_LEN:
825 case SSH_KEX_NL_SHK_ALGS_LEN:
826 case SSH_KEX_NL_EACTS_ALGS_LEN:
827 case SSH_KEX_NL_EASTC_ALGS_LEN:
828 case SSH_KEX_NL_MACTS_ALGS_LEN:
829 case SSH_KEX_NL_MASTC_ALGS_LEN:
830 case SSH_KEX_NL_CACTS_ALGS_LEN:
831 case SSH_KEX_NL_CASTC_ALGS_LEN:
832 case SSH_KEX_NL_LCTS_ALGS_LEN:
833 case SSH_KEX_NL_LSTC_ALGS_LEN:
834 case SSH_KEX_STATE_ECDH_KEYLEN:
835
836 pss->len = (pss->len << 8) | *p++;
837 if (++pss->ctr != 4)
838 break;
839
840 switch (pss->parser_state) {
841 case SSH_KEX_STATE_ECDH_KEYLEN:
842 pss->parser_state = SSH_KEX_STATE_ECDH_Q_C;
843 break;
844 default:
845 pss->parser_state++;
846 if (pss->len == 0)
847 pss->parser_state++;
848 break;
849 }
850 pss->ctr = 0;
851 pss->npos = 0;
852 if (pss->msg_len - pss->pos < pss->len) {
853 lwsl_notice("sanity: length %d - %d < %d\n",
854 pss->msg_len, pss->pos, pss->len);
855 goto bail;
856 }
857 break;
858
859 case SSH_KEX_NL_KEX_ALGS:
860 case SSH_KEX_NL_SHK_ALGS:
861 case SSH_KEX_NL_EACTS_ALGS:
862 case SSH_KEX_NL_EASTC_ALGS:
863 case SSH_KEX_NL_MACTS_ALGS:
864 case SSH_KEX_NL_MASTC_ALGS:
865 case SSH_KEX_NL_CACTS_ALGS:
866 case SSH_KEX_NL_CASTC_ALGS:
867 case SSH_KEX_NL_LCTS_ALGS:
868 case SSH_KEX_NL_LSTC_ALGS:
869 if (*p != ',') {
870 if (pss->npos < sizeof(pss->name) - 1)
871 pss->name[pss->npos++] = *p;
872 } else {
873 pss->name[pss->npos] = '\0';
874 pss->npos = 0;
875 handle_name(pss);
876 }
877 p++;
878 if (!--pss->len) {
879 pss->name[pss->npos] = '\0';
880 if (pss->npos)
881 handle_name(pss);
882 pss->parser_state++;
883 break;
884 }
885 break;
886
887 case SSH_KEX_FIRST_PKT:
888 pss->first_coming = !!*p++;
889 pss->parser_state = SSH_KEX_RESERVED;
890 break;
891
892 case SSH_KEX_RESERVED:
893 pss->len = (pss->len << 8) | *p++;
894 if (++pss->ctr != 4)
895 break;
896 pss->ctr = 0;
897 if (pss->msg_padding) {
898 pss->copy_to_I_C = 0;
899 pss->parser_state = SSHS_MSG_EAT_PADDING;
900 break;
901 }
902 pss->parser_state = SSHS_MSG_LEN;
903 break;
904
905 case SSH_KEX_STATE_ECDH_Q_C:
906 if (pss->len != 32) {
907 lwsl_notice("wrong key len\n");
908 goto bail;
909 }
910 pss->kex->Q_C[pss->ctr++] = *p++;
911 if (pss->ctr != 32)
912 break;
913 lwsl_info("Q_C parsed\n");
914 pss->parser_state = SSHS_MSG_EAT_PADDING;
915 break;
916
917 case SSH_KEX_STATE_SKIP:
918 if (pss->pos - 4 < pss->msg_len) {
919 p++;
920 break;
921 }
922 lwsl_debug("skip done pos %d, msg_len %d len=%ld, \n",
923 pss->pos, pss->msg_len, (long)len);
924 pss->parser_state = SSHS_MSG_LEN;
925 pss->ctr = 0;
926 break;
927
928 case SSHS_MSG_EAT_PADDING:
929 p++;
930 if (--pss->msg_padding)
931 break;
932 if (pss->msg_len + 4 != pss->pos) {
933 lwsl_notice("sanity: kex end mismatch %d %d\n",
934 pss->pos, pss->msg_len);
935 goto bail;
936 }
937
938 switch (pss->msg_id) {
939 case SSH_MSG_KEX_ECDH_INIT:
940 if (pss->kex->match_bitfield != 0xff) {
941 lwsl_notice("unable to negotiate\n");
942 goto bail;
943 }
944 if (kex_ecdh(pss, pss->kex->kex_r,
945 &pss->kex->kex_r_len)) {
946 lwsl_notice("hex_ecdh failed\n");
947 goto bail;
948 }
949 write_task(pss, NULL, SSH_WT_OFFER_REPLY);
950 break;
951 }
952
953 pss->parser_state = SSHS_MSG_LEN;
954 pss->ctr = 0;
955 break;
956
957 case SSHS_GET_STRING_LEN:
958 pss->npos = 0;
959 pss->len = (pss->len << 8) | *p++;
960 if (++pss->ctr != 4)
961 break;
962 pss->ctr = 0;
963 pss->parser_state = SSHS_GET_STRING;
964 break;
965
966 case SSHS_GET_STRING:
967 if (pss->npos >= sizeof(pss->name) - 1) {
968 lwsl_notice("non-alloc string too big\n");
969 goto bail;
970 }
971 pss->name[pss->npos++] = *p++;
972 if (pss->npos != pss->len)
973 break;
974
975 pss->name[pss->npos] = '\0';
976 pss->parser_state = pss->state_after_string;
977 goto again;
978
979 case SSHS_GET_STRING_LEN_ALLOC:
980 pss->npos = 0;
981 pss->len = (pss->len << 8) | *p++;
982 if (++pss->ctr != 4)
983 break;
984 pss->ctr = 0;
985 pss->last_alloc = sshd_zalloc(pss->len + 1);
986 lwsl_debug("SSHS_GET_STRING_LEN_ALLOC: %p, state %d\n",
987 pss->last_alloc, pss->state_after_string);
988 if (!pss->last_alloc) {
989 lwsl_notice("alloc string too big\n");
990 goto bail;
991 }
992 pss->parser_state = SSHS_GET_STRING_ALLOC;
993 break;
994
995 case SSHS_GET_STRING_ALLOC:
996 if (pss->npos >= pss->len)
997 goto bail;
998 pss->last_alloc[pss->npos++] = *p++;
999 if (pss->npos != pss->len)
1000 break;
1001 pss->last_alloc[pss->npos] = '\0';
1002 pss->parser_state = pss->state_after_string;
1003 goto again;
1004
1005 /*
1006 * User Authentication
1007 */
1008
1009 case SSHS_DO_SERVICE_REQUEST:
1010 pss->okayed_userauth = 1;
1011 pss->parser_state = SSHS_MSG_EAT_PADDING;
1012 /*
1013 * this only 'accepts' that we can negotiate auth for
1014 * this service, not accepts the auth
1015 */
1016 write_task(pss, NULL, SSH_WT_UA_ACCEPT);
1017 break;
1018
1019 case SSHS_DO_UAR_SVC:
1020 pss->ua->username = (char *)pss->last_alloc;
1021 pss->last_alloc = NULL; /* it was adopted */
1022 state_get_string_alloc(pss, SSHS_DO_UAR_PUBLICKEY);
1023 /* destroyed with UA struct */
1024 break;
1025
1026 case SSHS_DO_UAR_PUBLICKEY:
1027 pss->ua->service = (char *)pss->last_alloc;
1028 pss->last_alloc = NULL; /* it was adopted */
1029
1030 /* Sect 5, RFC4252
1031 *
1032 * The 'user name' and 'service name' are repeated in
1033 * every new authentication attempt, and MAY change.
1034 *
1035 * The server implementation MUST carefully check them
1036 * in every message, and MUST flush any accumulated
1037 * authentication states if they change. If it is
1038 * unable to flush an authentication state, it MUST
1039 * disconnect if the 'user name' or 'service name'
1040 * changes.
1041 */
1042
1043 if (pss->seen_auth_req_before && (
1044 strcmp(pss->ua->username,
1045 pss->last_auth_req_username) ||
1046 strcmp(pss->ua->service,
1047 pss->last_auth_req_service))) {
1048 lwsl_notice("username / svc changed\n");
1049
1050 goto bail;
1051 }
1052
1053 pss->seen_auth_req_before = 1;
1054 lws_strncpy(pss->last_auth_req_username,
1055 pss->ua->username,
1056 sizeof(pss->last_auth_req_username));
1057 lws_strncpy(pss->last_auth_req_service,
1058 pss->ua->service,
1059 sizeof(pss->last_auth_req_service));
1060
1061 if (strcmp(pss->ua->service, "ssh-connection"))
1062 goto ua_fail;
1063 state_get_string(pss, SSHS_NVC_DO_UAR_CHECK_PUBLICKEY);
1064 break;
1065
1066 case SSHS_NVC_DO_UAR_CHECK_PUBLICKEY:
1067 if (!strcmp(pss->name, "none")) {
1068 /* we must fail it */
1069 lwsl_info("got 'none' req, refusing\n");
1070 goto ua_fail;
1071 }
1072
1073 if (strcmp(pss->name, "publickey")) {
1074 lwsl_notice("expected 'publickey' got '%s'\n",
1075 pss->name);
1076 goto ua_fail;
1077 }
1078 pss->parser_state = SSHS_DO_UAR_SIG_PRESENT;
1079 break;
1080
1081 case SSHS_DO_UAR_SIG_PRESENT:
1082 lwsl_info("SSHS_DO_UAR_SIG_PRESENT\n");
1083 pss->ua->sig_present = *p++;
1084 state_get_string_alloc(pss, SSHS_NVC_DO_UAR_ALG);
1085 /* destroyed with UA struct */
1086 break;
1087
1088 case SSHS_NVC_DO_UAR_ALG:
1089 pss->ua->alg = (char *)pss->last_alloc;
1090 pss->last_alloc = NULL; /* it was adopted */
1091 if (rsa_hash_alg_from_ident(pss->ua->alg) < 0) {
1092 lwsl_notice("unknown alg\n");
1093 goto ua_fail;
1094 }
1095 state_get_string_alloc(pss, SSHS_NVC_DO_UAR_PUBKEY_BLOB);
1096 /* destroyed with UA struct */
1097 break;
1098
1099 case SSHS_NVC_DO_UAR_PUBKEY_BLOB:
1100 pss->ua->pubkey = pss->last_alloc;
1101 pss->last_alloc = NULL; /* it was adopted */
1102 pss->ua->pubkey_len = pss->npos;
1103 /*
1104 * RFC4253
1105 *
1106 * ssh-rsa
1107 *
1108 * The structure inside the blob is
1109 *
1110 * mpint e
1111 * mpint n
1112 *
1113 * Let's see if this key is authorized
1114 */
1115
1116 n = 1;
1117 if (pss->vhd->ops && pss->vhd->ops->is_pubkey_authorized)
1118 n = pss->vhd->ops->is_pubkey_authorized(
1119 pss->ua->username, pss->ua->alg,
1120 pss->ua->pubkey, pss->ua->pubkey_len);
1121 if (n) {
1122 lwsl_info("rejecting peer pubkey\n");
1123 goto ua_fail;
1124 }
1125
1126 if (pss->ua->sig_present) {
1127 state_get_string_alloc(pss, SSHS_NVC_DO_UAR_SIG);
1128 /* destroyed with UA struct */
1129 break;
1130 }
1131
1132 /*
1133 * This key is at least one we would be prepared
1134 * to accept if he really has it... since no sig
1135 * client should resend everything with a sig
1136 * appended. OK it and delete this initial UA
1137 */
1138 write_task(pss, NULL, SSH_WT_UA_PK_OK);
1139 pss->parser_state = SSHS_MSG_EAT_PADDING;
1140 break;
1141
1142 case SSHS_NVC_DO_UAR_SIG:
1143 /*
1144 * Now the pubkey is coming with a sig
1145 */
1146 /* Sect 5.1 RFC4252
1147 *
1148 * SSH_MSG_USERAUTH_SUCCESS MUST be sent only once.
1149 * When SSH_MSG_USERAUTH_SUCCESS has been sent, any
1150 * further authentication requests received after that
1151 * SHOULD be silently ignored.
1152 */
1153 if (pss->ssh_auth_state == SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS) {
1154 lwsl_info("Silently ignoring auth req after accepted\n");
1155 goto ua_fail_silently;
1156 }
1157 lwsl_info("SSHS_DO_UAR_SIG\n");
1158 pss->ua->sig = pss->last_alloc;
1159 pss->last_alloc = NULL; /* it was adopted */
1160 pss->ua->sig_len = pss->npos;
1161 pss->parser_state = SSHS_MSG_EAT_PADDING;
1162
1163 /*
1164 * RFC 4252 p9
1165 *
1166 * The value of 'signature' is a signature with
1167 * the private host key of the following data, in
1168 * this order:
1169 *
1170 * string session identifier
1171 * byte SSH_MSG_USERAUTH_REQUEST
1172 * string user name
1173 * string service name
1174 * string "publickey"
1175 * boolean TRUE
1176 * string public key algorithm name
1177 * string public key to be used for auth
1178 *
1179 * We reproduce the signature plaintext and the
1180 * hash, and then decrypt the incoming signed block.
1181 * What comes out is some ASN1, in there is the
1182 * hash decrypted. We find it and confirm it
1183 * matches the hash we computed ourselves.
1184 *
1185 * First step is generate the sig plaintext
1186 */
1187 n = 4 + 32 +
1188 1 +
1189 4 + (int)strlen(pss->ua->username) +
1190 4 + (int)strlen(pss->ua->service) +
1191 4 + 9 +
1192 1 +
1193 4 + (int)strlen(pss->ua->alg) +
1194 4 + (int)pss->ua->pubkey_len;
1195
1196 ps = sshd_zalloc(n);
1197 if (!ps) {
1198 lwsl_notice("OOM 4\n");
1199 goto ua_fail;
1200 }
1201
1202 pp = ps;
1203 lws_buf(&pp, pss->session_id, 32);
1204 *pp++ = SSH_MSG_USERAUTH_REQUEST;
1205 lws_cstr(&pp, pss->ua->username, 64);
1206 lws_cstr(&pp, pss->ua->service, 64);
1207 lws_cstr(&pp, "publickey", 64);
1208 *pp++ = 1;
1209 lws_cstr(&pp, pss->ua->alg, 64);
1210 lws_buf(&pp, pss->ua->pubkey, pss->ua->pubkey_len);
1211
1212 /* Next hash the plaintext */
1213
1214 if (lws_genhash_init(&pss->ua->hash_ctx,
1215 rsa_hash_alg_from_ident(pss->ua->alg))) {
1216 lwsl_notice("genhash init failed\n");
1217 free(ps);
1218 goto ua_fail;
1219 }
1220
1221 if (lws_genhash_update(&pss->ua->hash_ctx, ps, pp - ps)) {
1222 lwsl_notice("genhash update failed\n");
1223 free(ps);
1224 goto ua_fail;
1225 }
1226 lws_genhash_destroy(&pss->ua->hash_ctx, hash);
1227 free(ps);
1228
1229 /*
1230 * Prepare the RSA decryption context: load in
1231 * the E and N factors
1232 */
1233
1234 memset(e, 0, sizeof(e));
1235 pp = pss->ua->pubkey;
1236 m = lws_g32(&pp);
1237 pp += m;
1238 m = lws_g32(&pp);
1239 e[LWS_GENCRYPTO_RSA_KEYEL_E].buf = pp;
1240 e[LWS_GENCRYPTO_RSA_KEYEL_E].len = m;
1241 pp += m;
1242 m = lws_g32(&pp);
1243 e[LWS_GENCRYPTO_RSA_KEYEL_N].buf = pp;
1244 e[LWS_GENCRYPTO_RSA_KEYEL_N].len = m;
1245
1246 if (lws_genrsa_create(&ctx, e, pss->vhd->context,
1247 LGRSAM_PKCS1_1_5,
1248 LWS_GENHASH_TYPE_UNKNOWN))
1249 goto ua_fail;
1250
1251 /*
1252 * point to the encrypted signature payload we
1253 * were sent
1254 */
1255 pp = pss->ua->sig;
1256 m = lws_g32(&pp);
1257 pp += m;
1258 m = lws_g32(&pp);
1259
1260 /*
1261 * decrypt it, resulting in an error, or some ASN1
1262 * including the decrypted signature
1263 */
1264 otmp = sshd_zalloc(m);
1265 if (!otmp)
1266 /* ua_fail1 frees bn_e, bn_n and rsa */
1267 goto ua_fail1;
1268
1269 n = lws_genrsa_public_decrypt(&ctx, pp, m, otmp, m);
1270 if (n > 0) {
1271 /* the decrypted sig is in ASN1 format */
1272 m = 0;
1273 while ((int)m < n) {
1274 /* sig payload */
1275 if (otmp[m] == 0x04 &&
1276 otmp[m + 1] == lws_genhash_size(
1277 pss->ua->hash_ctx.type)) {
1278 m = memcmp(&otmp[m + 2], hash,
1279 lws_genhash_size(pss->ua->hash_ctx.type));
1280 break;
1281 }
1282 /* go into these */
1283 if (otmp[m] == 0x30) {
1284 m += 2;
1285 continue;
1286 }
1287 /* otherwise skip payloads */
1288 m += otmp[m + 1] + 2;
1289 }
1290 }
1291
1292 free(otmp);
1293 lws_genrsa_destroy(&ctx);
1294
1295 /*
1296 * if no good, m is nonzero and inform peer
1297 */
1298 if (n <= 0) {
1299 lwsl_notice("hash sig verify fail: %d\n", m);
1300 goto ua_fail;
1301 }
1302
1303 /* if it checks out, inform peer */
1304
1305 lwsl_info("sig check OK\n");
1306
1307 /* Sect 5.1 RFC4252
1308 *
1309 * SSH_MSG_USERAUTH_SUCCESS MUST be sent only once.
1310 * When SSH_MSG_USERAUTH_SUCCESS has been sent, any
1311 * further authentication requests received after that
1312 * SHOULD be silently ignored.
1313 */
1314 pss->ssh_auth_state = SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS;
1315
1316 write_task(pss, NULL, SSH_WT_UA_SUCCESS);
1317 lws_ua_destroy(pss);
1318 break;
1319
1320 /*
1321 * Channels
1322 */
1323
1324 case SSHS_GET_U32:
1325 pss->len = (pss->len << 8) | *p++;
1326 if (++pss->ctr != 4)
1327 break;
1328 pss->ctr = 0;
1329 pss->parser_state = pss->state_after_string;
1330 goto again;
1331
1332 /*
1333 * Channel: Disconnect
1334 */
1335
1336 case SSHS_NVC_DISCONNECT_REASON:
1337 pss->disconnect_reason = pss->len;
1338 state_get_string_alloc(pss, SSHS_NVC_DISCONNECT_DESC);
1339 break;
1340
1341 case SSHS_NVC_DISCONNECT_DESC:
1342 pss->disconnect_desc = (char *)pss->last_alloc;
1343 pss->last_alloc = NULL; /* it was adopted */
1344 state_get_string(pss, SSHS_NVC_DISCONNECT_LANG);
1345 break;
1346
1347 case SSHS_NVC_DISCONNECT_LANG:
1348 lwsl_notice("SSHS_NVC_DISCONNECT_LANG\n");
1349 if (pss->vhd->ops && pss->vhd->ops->disconnect_reason)
1350 pss->vhd->ops->disconnect_reason(
1351 pss->disconnect_reason,
1352 pss->disconnect_desc, pss->name);
1353 ssh_free_set_NULL(pss->last_alloc);
1354 break;
1355
1356 /*
1357 * Channel: Open
1358 */
1359
1360 case SSHS_NVC_CHOPEN_TYPE:
1361 /* channel open */
1362 if (strcmp(pss->name, "session")) {
1363 lwsl_notice("Failing on not session\n");
1364 pss->reason = 3;
1365 goto ch_fail;
1366 }
1367 lwsl_info("SSHS_NVC_CHOPEN_TYPE: creating session\n");
1368 pss->ch_temp = sshd_zalloc(sizeof(*pss->ch_temp));
1369 if (!pss->ch_temp)
1370 return -1;
1371
1372 pss->ch_temp->type = SSH_CH_TYPE_SESSION;
1373 pss->ch_temp->pss = pss;
1374 state_get_u32(pss, SSHS_NVC_CHOPEN_SENDER_CH);
1375 break;
1376
1377 case SSHS_NVC_CHOPEN_SENDER_CH:
1378 pss->ch_temp->sender_ch = pss->len;
1379 state_get_u32(pss, SSHS_NVC_CHOPEN_WINSIZE);
1380 break;
1381 case SSHS_NVC_CHOPEN_WINSIZE:
1382 lwsl_info("Initial window set to %d\n", pss->len);
1383 pss->ch_temp->window = pss->len;
1384 state_get_u32(pss, SSHS_NVC_CHOPEN_PKTSIZE);
1385 break;
1386 case SSHS_NVC_CHOPEN_PKTSIZE:
1387 pss->ch_temp->max_pkt = pss->len;
1388 pss->ch_temp->peer_window_est = LWS_SSH_INITIAL_WINDOW;
1389 pss->ch_temp->server_ch = pss->next_ch_num++;
1390 /*
1391 * add us to channel list... leave as ch_temp
1392 * as write task needs it and will NULL down
1393 */
1394 lwsl_info("creating new session ch\n");
1395 pss->ch_temp->next = pss->ch_list;
1396 pss->ch_list = pss->ch_temp;
1397 if (pss->vhd->ops && pss->vhd->ops->channel_create)
1398 pss->vhd->ops->channel_create(pss->wsi,
1399 &pss->ch_temp->priv);
1400 write_task(pss, pss->ch_temp, SSH_WT_CH_OPEN_CONF);
1401 pss->parser_state = SSHS_MSG_EAT_PADDING;
1402 break;
1403
1404 /*
1405 * SSH_MSG_CHANNEL_REQUEST
1406 */
1407
1408 case SSHS_NVC_CHRQ_RECIP:
1409 pss->ch_recip = pss->len;
1410 state_get_string(pss, SSHS_NVC_CHRQ_TYPE);
1411 break;
1412
1413 case SSHS_NVC_CHRQ_TYPE:
1414 pss->parser_state = SSHS_CHRQ_WANT_REPLY;
1415 break;
1416
1417 case SSHS_CHRQ_WANT_REPLY:
1418 pss->rq_want_reply = *p++;
1419 lwsl_info("SSHS_CHRQ_WANT_REPLY: %s, wantrep: %d\n",
1420 pss->name, pss->rq_want_reply);
1421
1422 pss->ch_temp = ssh_get_server_ch(pss, pss->ch_recip);
1423
1424 /* after this they differ by the request */
1425
1426 /*
1427 * a PTY for a shell
1428 */
1429 if (!strcmp(pss->name, "pty-req")) {
1430 state_get_string(pss, SSHS_NVC_CHRQ_TERM);
1431 break;
1432 }
1433 /*
1434 * a shell
1435 */
1436 if (!strcmp(pss->name, "shell")) {
1437 pss->channel_doing_spawn = pss->ch_temp->server_ch;
1438 if (pss->vhd->ops && pss->vhd->ops->shell &&
1439 !pss->vhd->ops->shell(pss->ch_temp->priv,
1440 pss->wsi,
1441 lws_ssh_exec_finish, pss->ch_temp)) {
1442
1443 if (pss->rq_want_reply)
1444 write_task_insert(pss, pss->ch_temp,
1445 SSH_WT_CHRQ_SUCC);
1446 pss->parser_state = SSHS_MSG_EAT_PADDING;
1447 break;
1448 }
1449
1450 goto chrq_fail;
1451 }
1452 /*
1453 * env vars to be set in the shell
1454 */
1455 if (!strcmp(pss->name, "env")) {
1456 state_get_string(pss, SSHS_NVC_CHRQ_ENV_NAME);
1457 break;
1458 }
1459
1460 /*
1461 * exec something
1462 */
1463 if (!strcmp(pss->name, "exec")) {
1464 state_get_string_alloc(pss, SSHS_NVC_CHRQ_EXEC_CMD);
1465 break;
1466 }
1467
1468 /*
1469 * spawn a subsystem
1470 */
1471 if (!strcmp(pss->name, "subsystem")) {
1472 lwsl_notice("subsystem\n");
1473 state_get_string_alloc(pss,
1474 SSHS_NVC_CHRQ_SUBSYSTEM);
1475 break;
1476 }
1477
1478 if (pss->rq_want_reply)
1479 goto chrq_fail;
1480
1481 pss->parser_state = SSH_KEX_STATE_SKIP;
1482 break;
1483
1484 /* CHRQ pty-req */
1485
1486 case SSHS_NVC_CHRQ_TERM:
1487 memcpy(pss->args.pty.term, pss->name,
1488 sizeof(pss->args.pty.term) - 1);
1489 state_get_u32(pss, SSHS_NVC_CHRQ_TW);
1490 break;
1491 case SSHS_NVC_CHRQ_TW:
1492 pss->args.pty.width_ch = pss->len;
1493 state_get_u32(pss, SSHS_NVC_CHRQ_TH);
1494 break;
1495 case SSHS_NVC_CHRQ_TH:
1496 pss->args.pty.height_ch = pss->len;
1497 state_get_u32(pss, SSHS_NVC_CHRQ_TWP);
1498 break;
1499 case SSHS_NVC_CHRQ_TWP:
1500 pss->args.pty.width_px = pss->len;
1501 state_get_u32(pss, SSHS_NVC_CHRQ_THP);
1502 break;
1503 case SSHS_NVC_CHRQ_THP:
1504 pss->args.pty.height_px = pss->len;
1505 state_get_string_alloc(pss, SSHS_NVC_CHRQ_MODES);
1506 break;
1507 case SSHS_NVC_CHRQ_MODES:
1508 /* modes is a stream of byte-pairs, not a string */
1509 pss->args.pty.modes = (char *)pss->last_alloc;
1510 pss->last_alloc = NULL; /* it was adopted */
1511 pss->args.pty.modes_len = pss->npos;
1512 n = 0;
1513 if (pss->vhd->ops && pss->vhd->ops->pty_req)
1514 n = pss->vhd->ops->pty_req(pss->ch_temp->priv,
1515 &pss->args.pty);
1516 ssh_free_set_NULL(pss->args.pty.modes);
1517 if (n)
1518 goto chrq_fail;
1519 if (pss->rq_want_reply)
1520 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC);
1521 pss->parser_state = SSHS_MSG_EAT_PADDING;
1522 break;
1523
1524 /* CHRQ env */
1525
1526 case SSHS_NVC_CHRQ_ENV_NAME:
1527 strcpy(pss->args.aux, pss->name);
1528 state_get_string(pss, SSHS_NVC_CHRQ_ENV_VALUE);
1529 break;
1530
1531 case SSHS_NVC_CHRQ_ENV_VALUE:
1532 if (pss->vhd->ops && pss->vhd->ops->set_env)
1533 if (pss->vhd->ops->set_env(pss->ch_temp->priv,
1534 pss->args.aux, pss->name))
1535 goto chrq_fail;
1536 pss->parser_state = SSHS_MSG_EAT_PADDING;
1537 break;
1538
1539 /* CHRQ exec */
1540
1541 case SSHS_NVC_CHRQ_EXEC_CMD:
1542 /*
1543 * byte SSH_MSG_CHANNEL_REQUEST
1544 * uint32 recipient channel
1545 * string "exec"
1546 * boolean want reply
1547 * string command
1548 *
1549 * This message will request that the server start the
1550 * execution of the given command. The 'command' string
1551 * may contain a path. Normal precautions MUST be taken
1552 * to prevent the execution of unauthorized commands.
1553 *
1554 * scp sends "scp -t /path/..."
1555 */
1556 lwsl_info("exec cmd: %s %02X\n", pss->last_alloc, *p);
1557
1558 pss->channel_doing_spawn = pss->ch_temp->server_ch;
1559
1560 if (pss->vhd->ops && pss->vhd->ops->exec &&
1561 !pss->vhd->ops->exec(pss->ch_temp->priv, pss->wsi,
1562 (const char *)pss->last_alloc,
1563 lws_ssh_exec_finish, pss->ch_temp)) {
1564 ssh_free_set_NULL(pss->last_alloc);
1565 if (pss->rq_want_reply)
1566 write_task_insert(pss, pss->ch_temp,
1567 SSH_WT_CHRQ_SUCC);
1568
1569 pss->parser_state = SSHS_MSG_EAT_PADDING;
1570 break;
1571 }
1572
1573 /*
1574 * even if he doesn't want to exec it, we know how to
1575 * fake scp
1576 */
1577
1578 /* we only alloc "exec" of scp for scp destination */
1579 n = 1;
1580 if (pss->last_alloc[0] != 's' ||
1581 pss->last_alloc[1] != 'c' ||
1582 pss->last_alloc[2] != 'p' ||
1583 pss->last_alloc[3] != ' ')
1584 /* disallow it */
1585 n = 0;
1586
1587 ssh_free_set_NULL(pss->last_alloc);
1588 if (!n)
1589 goto chrq_fail;
1590
1591 /* our channel speaks SCP protocol now */
1592
1593 scp = sshd_zalloc(sizeof(*scp));
1594 if (!scp)
1595 return -1;
1596
1597 pss->ch_temp->type = SSH_CH_TYPE_SCP;
1598 pss->ch_temp->sub = (lws_subprotocol *)scp;
1599
1600 scp->ips = SSHS_SCP_COLLECTSTR;
1601
1602 if (pss->rq_want_reply)
1603 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_SUCC);
1604
1605 /* we start the scp protocol first by sending an ACK */
1606 write_task(pss, pss->ch_temp, SSH_WT_SCP_ACK_OKAY);
1607
1608 pss->parser_state = SSHS_MSG_EAT_PADDING;
1609 break;
1610
1611 case SSHS_NVC_CHRQ_SUBSYSTEM:
1612 lwsl_notice("subsystem: %s", pss->last_alloc);
1613 n = 0;
1614 #if 0
1615 if (!strcmp(pss->name, "sftp")) {
1616 lwsl_notice("SFTP session\n");
1617 pss->ch_temp->type = SSH_CH_TYPE_SFTP;
1618 n = 1;
1619 }
1620 #endif
1621 ssh_free_set_NULL(pss->last_alloc);
1622 // if (!n)
1623 goto ch_fail;
1624 #if 0
1625 if (pss->rq_want_reply)
1626 write_task(pss, ssh_get_server_ch(pss,
1627 pss->ch_recip), SSH_WT_CHRQ_SUCC);
1628 pss->parser_state = SSHS_MSG_EAT_PADDING;
1629 break;
1630 #endif
1631
1632 /* SSH_MSG_CHANNEL_DATA */
1633
1634 case SSHS_NVC_CD_RECIP:
1635 pss->ch_recip = pss->len;
1636
1637 ch = ssh_get_server_ch(pss, pss->ch_recip);
1638 ch->peer_window_est -= pss->msg_len;
1639
1640 if (pss->msg_len < sizeof(pss->name))
1641 state_get_string(pss, SSHS_NVC_CD_DATA);
1642 else
1643 state_get_string_alloc(pss,
1644 SSHS_NVC_CD_DATA_ALLOC);
1645 break;
1646
1647 case SSHS_NVC_CD_DATA_ALLOC:
1648 case SSHS_NVC_CD_DATA:
1649 /*
1650 * Actual protocol incoming payload
1651 */
1652 if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC)
1653 pp = pss->last_alloc;
1654 else
1655 pp = (uint8_t *)pss->name;
1656 lwsl_info("SSHS_NVC_CD_DATA\n");
1657
1658 ch = ssh_get_server_ch(pss, pss->ch_recip);
1659 switch (ch->type) {
1660 case SSH_CH_TYPE_SCP:
1661 scp = &ch->sub->scp;
1662 switch (scp->ips) {
1663 case SSHS_SCP_COLLECTSTR:
1664 /* gather the ascii-coded headers */
1665 for (n = 0; n < (int)pss->npos; n++)
1666 lwsl_notice("0x%02X %c\n",
1667 pp[n], pp[n]);
1668
1669 /* Header triggers the transfer? */
1670 if (pp[0] == 'C' && pp[pss->npos - 1] == '\x0a') {
1671 while (*pp != ' ' && *pp != '\x0a')
1672 pp++;
1673 if (*pp++ != ' ') {
1674 write_task(pss, ch,
1675 SSH_WT_SCP_ACK_ERROR);
1676 pss->parser_state = SSHS_MSG_EAT_PADDING;
1677 break;
1678 }
1679 scp->len = atoll((const char *)pp);
1680 lwsl_notice("scp payload %llu expected\n",
1681 (unsigned long long)scp->len);
1682 scp->ips = SSHS_SCP_PAYLOADIN;
1683 }
1684 /* ack it */
1685 write_task(pss, pss->ch_temp,
1686 SSH_WT_SCP_ACK_OKAY);
1687 break;
1688 case SSHS_SCP_PAYLOADIN:
1689 /* the scp file payload */
1690 if (pss->vhd->ops)
1691 pss->vhd->ops->rx(ch->priv,
1692 pss->wsi, pp, pss->npos);
1693 if (scp->len >= pss->npos)
1694 scp->len -= pss->npos;
1695 else
1696 scp->len = 0;
1697 if (!scp->len) {
1698 lwsl_notice("scp txfer completed\n");
1699 scp->ips = SSHS_SCP_COLLECTSTR;
1700 break;
1701 }
1702 break;
1703 }
1704 break;
1705 default: /* scp payload */
1706 if (pss->vhd->ops)
1707 pss->vhd->ops->rx(ch->priv, pss->wsi,
1708 pp, pss->npos);
1709 break;
1710 }
1711 if (pss->parser_state == SSHS_NVC_CD_DATA_ALLOC)
1712 ssh_free_set_NULL(pss->last_alloc);
1713
1714 if (ch->peer_window_est < 32768) {
1715 write_task(pss, ch, SSH_WT_WINDOW_ADJUST);
1716 ch->peer_window_est += 32768;
1717 lwsl_info("extra peer WINDOW_ADJUST (~ %d)\n",
1718 ch->peer_window_est);
1719 }
1720
1721 pss->parser_state = SSHS_MSG_EAT_PADDING;
1722 break;
1723
1724 case SSHS_NVC_WA_RECIP:
1725 pss->ch_recip = pss->len;
1726 state_get_u32(pss, SSHS_NVC_WA_ADD);
1727 break;
1728
1729 case SSHS_NVC_WA_ADD:
1730 ch = ssh_get_server_ch(pss, pss->ch_recip);
1731 if (ch) {
1732 ch->window += pss->len;
1733 lwsl_notice("got additional window %d (now %d)\n",
1734 pss->len, ch->window);
1735 }
1736 pss->parser_state = SSHS_MSG_EAT_PADDING;
1737 break;
1738
1739 /*
1740 * channel close
1741 */
1742
1743 case SSHS_NVC_CH_EOF:
1744 /*
1745 * No explicit response is sent to this
1746 * message. However, the application may send
1747 * EOF to whatever is at the other end of the
1748 * channel. Note that the channel remains open
1749 * after this message, and more data may still
1750 * be sent in the other direction. This message
1751 * does not consume window space and can be sent
1752 * even if no window space is available.
1753 */
1754 lwsl_notice("SSH_MSG_CHANNEL_EOF: %d\n", pss->ch_recip);
1755 ch = ssh_get_server_ch(pss, pss->ch_recip);
1756 if (!ch) {
1757 lwsl_notice("unknown ch %d\n", pss->ch_recip);
1758 return -1;
1759 }
1760
1761 if (!ch->scheduled_close) {
1762 lwsl_notice("scheduling CLOSE\n");
1763 ch->scheduled_close = 1;
1764 write_task(pss, ch, SSH_WT_CH_CLOSE);
1765 }
1766 pss->parser_state = SSHS_MSG_EAT_PADDING;
1767 break;
1768
1769 case SSHS_NVC_CH_CLOSE:
1770 /*
1771 * When either party wishes to terminate the
1772 * channel, it sends SSH_MSG_CHANNEL_CLOSE.
1773 * Upon receiving this message, a party MUST
1774 * send back an SSH_MSG_CHANNEL_CLOSE unless it
1775 * has already sent this message for the
1776 * channel. The channel is considered closed
1777 * for a party when it has both sent and
1778 * received SSH_MSG_CHANNEL_CLOSE, and the
1779 * party may then reuse the channel number.
1780 * A party MAY send SSH_MSG_CHANNEL_CLOSE
1781 * without having sent or received
1782 * SSH_MSG_CHANNEL_EOF.
1783 */
1784 lwsl_notice("SSH_MSG_CHANNEL_CLOSE ch %d\n",
1785 pss->ch_recip);
1786 ch = ssh_get_server_ch(pss, pss->ch_recip);
1787 if (!ch)
1788 goto bail;
1789
1790 pss->parser_state = SSHS_MSG_EAT_PADDING;
1791
1792 if (ch->sent_close) {
1793 /*
1794 * This is acking our sent close...
1795 * we can destroy the channel with no
1796 * further communication.
1797 */
1798 ssh_destroy_channel(pss, ch);
1799 break;
1800 }
1801
1802 ch->received_close = 1;
1803 ch->scheduled_close = 1;
1804 write_task(pss, ch, SSH_WT_CH_CLOSE);
1805 break;
1806
1807 default:
1808 break;
1809
1810 chrq_fail:
1811 lwsl_notice("chrq_fail\n");
1812 write_task(pss, pss->ch_temp, SSH_WT_CHRQ_FAILURE);
1813 pss->parser_state = SSH_KEX_STATE_SKIP;
1814 break;
1815
1816 ch_fail:
1817 if (pss->ch_temp) {
1818 free(pss->ch_temp);
1819 pss->ch_temp = NULL;
1820 }
1821 write_task(pss, pss->ch_temp, SSH_WT_CH_FAILURE);
1822 pss->parser_state = SSH_KEX_STATE_SKIP;
1823 break;
1824
1825 ua_fail1:
1826 lws_genrsa_destroy(&ctx);
1827 ua_fail:
1828 write_task(pss, NULL, SSH_WT_UA_FAILURE);
1829 ua_fail_silently:
1830 lws_ua_destroy(pss);
1831 /* Sect 4, RFC4252
1832 *
1833 * Additionally, the implementation SHOULD limit the
1834 * number of failed authentication attempts a client
1835 * may perform in a single session (the RECOMMENDED
1836 * limit is 20 attempts). If the threshold is
1837 * exceeded, the server SHOULD disconnect.
1838 */
1839 if (pss->count_auth_attempts++ > 20)
1840 goto bail;
1841
1842 pss->parser_state = SSH_KEX_STATE_SKIP;
1843 break;
1844 }
1845
1846 pss->pos++;
1847 }
1848
1849 return 0;
1850 bail:
1851 lws_kex_destroy(pss);
1852 lws_ua_destroy(pss);
1853
1854 return SSH_DISCONNECT_KEY_EXCHANGE_FAILED;
1855 }
1856
1857 static int
parse(struct per_session_data__sshd * pss,uint8_t * p,size_t len)1858 parse(struct per_session_data__sshd *pss, uint8_t *p, size_t len)
1859 {
1860 while (len--) {
1861
1862 if (pss->copy_to_I_C && pss->kex->I_C_payload_len <
1863 pss->kex->I_C_alloc_len &&
1864 pss->parser_state != SSHS_MSG_EAT_PADDING)
1865 pss->kex->I_C[pss->kex->I_C_payload_len++] = *p;
1866
1867 if (pss->active_keys_cts.valid &&
1868 pss->parser_state == SSHS_MSG_LEN)
1869 /* take a copy for full decrypt */
1870 pss->packet_assembly[pss->pa_pos++] = *p;
1871
1872 if (pss->active_keys_cts.valid &&
1873 pss->parser_state == SSHS_MSG_PADDING &&
1874 pss->msg_len) {
1875 /* we are going to have to decrypt it */
1876 uint32_t cp, l = pss->msg_len + 4 +
1877 pss->active_keys_cts.MAC_length;
1878 uint8_t pt[2048];
1879
1880 len++;
1881 cp = (uint32_t)len;
1882
1883 if (cp > l - pss->pa_pos)
1884 cp = l - pss->pa_pos;
1885
1886 if (cp > sizeof(pss->packet_assembly) -
1887 pss->pa_pos) {
1888 lwsl_err("Packet is too big to decrypt\n");
1889
1890 goto bail;
1891 }
1892 if (pss->msg_len < 2 + 4) {
1893 lwsl_err("packet too small\n");
1894
1895 goto bail;
1896 }
1897
1898 memcpy(&pss->packet_assembly[pss->pa_pos], p, cp);
1899 pss->pa_pos += cp;
1900 len -= cp;
1901 p += cp;
1902
1903 if (pss->pa_pos != l)
1904 return 0;
1905
1906 /* decrypt it */
1907 cp = lws_chacha_decrypt(&pss->active_keys_cts,
1908 pss->ssh_sequence_ctr_cts++,
1909 pss->packet_assembly,
1910 pss->pa_pos, pt);
1911 if (cp) {
1912 lwsl_notice("Decryption failed: %d\n", cp);
1913 goto bail;
1914 }
1915
1916 if (lws_ssh_parse_plaintext(pss, pt + 4, pss->msg_len))
1917 goto bail;
1918
1919 pss->pa_pos = 0;
1920 pss->ctr = 0;
1921 continue;
1922 }
1923
1924 if (lws_ssh_parse_plaintext(pss, p, 1))
1925 goto bail;
1926
1927 p++;
1928 }
1929
1930 return 0;
1931
1932 bail:
1933 lws_kex_destroy(pss);
1934 lws_ua_destroy(pss);
1935
1936 return SSH_DISCONNECT_KEY_EXCHANGE_FAILED;
1937 }
1938
1939 static uint32_t
pad_and_encrypt(uint8_t * dest,void * ps,uint8_t * pp,struct per_session_data__sshd * pss,int skip_pad)1940 pad_and_encrypt(uint8_t *dest, void *ps, uint8_t *pp,
1941 struct per_session_data__sshd *pss, int skip_pad)
1942 {
1943 uint32_t n;
1944
1945 if (!skip_pad)
1946 lws_pad_set_length(pss, ps, &pp, &pss->active_keys_stc);
1947 n = lws_ptr_diff(pp, ps);
1948
1949 if (!pss->active_keys_stc.valid) {
1950 memcpy(dest, ps, n);
1951 return n;
1952 }
1953
1954 lws_chacha_encrypt(&pss->active_keys_stc, pss->ssh_sequence_ctr_stc,
1955 ps, n, dest);
1956 n += pss->active_keys_stc.MAC_length;
1957
1958 return n;
1959 }
1960
1961 static int
lws_callback_raw_sshd(struct lws * wsi,enum lws_callback_reasons reason,void * user,void * in,size_t len)1962 lws_callback_raw_sshd(struct lws *wsi, enum lws_callback_reasons reason,
1963 void *user, void *in, size_t len)
1964 {
1965 struct per_session_data__sshd *pss =
1966 (struct per_session_data__sshd *)user, **p;
1967 struct per_vhost_data__sshd *vhd = NULL;
1968 uint8_t buf[LWS_PRE + 1024], *pp, *ps = &buf[LWS_PRE + 512], *ps1 = NULL;
1969 const struct lws_protocol_vhost_options *pvo;
1970 const struct lws_protocols *prot;
1971 struct lws_ssh_channel *ch;
1972 char lang[10];
1973 int n, m, o;
1974
1975 /*
1976 * Because we are an abstract protocol plugin, we will get called by
1977 * wsi that actually bind to a plugin "on top of us" that calls thru
1978 * to our callback.
1979 *
1980 * Under those circumstances, we can't simply get a pointer to our own
1981 * protocol from the wsi. If there's a pss already, we can get it from
1982 * there, but the first time for each connection we have to look it up.
1983 */
1984 if (pss && pss->vhd)
1985 vhd = (struct per_vhost_data__sshd *)
1986 lws_protocol_vh_priv_get(lws_get_vhost(wsi),
1987 pss->vhd->protocol);
1988 else
1989 if (lws_get_vhost(wsi))
1990 vhd = (struct per_vhost_data__sshd *)
1991 lws_protocol_vh_priv_get(lws_get_vhost(wsi),
1992 lws_vhost_name_to_protocol(
1993 lws_get_vhost(wsi), "lws-ssh-base"));
1994
1995 switch ((int)reason) {
1996 case LWS_CALLBACK_PROTOCOL_INIT:
1997 vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
1998 lws_get_protocol(wsi),
1999 sizeof(struct per_vhost_data__sshd));
2000 vhd->context = lws_get_context(wsi);
2001 vhd->protocol = lws_get_protocol(wsi);
2002 vhd->vhost = lws_get_vhost(wsi);
2003
2004 pvo = (const struct lws_protocol_vhost_options *)in;
2005 while (pvo) {
2006 /*
2007 * the user code passes the ops struct address to us
2008 * using a pvo (per-vhost option)
2009 */
2010 if (!strcmp(pvo->name, "ops"))
2011 vhd->ops = (const struct lws_ssh_ops *)pvo->value;
2012
2013 /*
2014 * the user code is telling us to get the ops struct
2015 * from another protocol's protocol.user pointer
2016 */
2017 if (!strcmp(pvo->name, "ops-from")) {
2018 prot = lws_vhost_name_to_protocol(vhd->vhost,
2019 pvo->value);
2020 if (prot)
2021 vhd->ops = (const struct lws_ssh_ops *)prot->user;
2022 else
2023 lwsl_err("%s: can't find protocol %s\n",
2024 __func__, pvo->value);
2025 }
2026
2027 pvo = pvo->next;
2028 }
2029
2030 if (!vhd->ops) {
2031 lwsl_err("ssh pvo \"ops\" is mandatory\n");
2032 return 1;
2033 }
2034 /*
2035 * The user code ops api_version has to be current
2036 */
2037 if (vhd->ops->api_version != LWS_SSH_OPS_VERSION) {
2038 lwsl_err("FATAL ops is api_version v%d but code is v%d\n",
2039 vhd->ops->api_version, LWS_SSH_OPS_VERSION);
2040 return 1;
2041 }
2042 break;
2043
2044 case LWS_CALLBACK_RAW_ADOPT:
2045 lwsl_info("LWS_CALLBACK_RAW_ADOPT\n");
2046 if (!vhd)
2047 return -1;
2048 pss->next = vhd->live_pss_list;
2049 vhd->live_pss_list = pss;
2050 pss->parser_state = SSH_INITIALIZE_TRANSIENT;
2051 pss->wsi = wsi;
2052 pss->vhd = vhd;
2053 pss->kex_state = KEX_STATE_EXPECTING_CLIENT_OFFER;
2054 pss->active_keys_cts.padding_alignment = 8;
2055 pss->active_keys_stc.padding_alignment = 8;
2056 if (lws_kex_create(pss))
2057 return -1;
2058 write_task(pss, NULL, SSH_WT_VERSION);
2059
2060 /* sect 4 RFC4252
2061 *
2062 * The server SHOULD have a timeout for authentication and
2063 * disconnect if the authentication has not been accepted
2064 * within the timeout period.
2065 *
2066 * The RECOMMENDED timeout period is 10 minutes.
2067 */
2068 lws_set_timeout(wsi,
2069 SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH, 10 * 60);
2070 break;
2071
2072 case LWS_CALLBACK_RAW_CLOSE:
2073 if (!pss)
2074 return -1;
2075 lwsl_info("LWS_CALLBACK_RAW_CLOSE\n");
2076 lws_kex_destroy(pss);
2077 lws_ua_destroy(pss);
2078
2079 ssh_free_set_NULL(pss->last_alloc);
2080
2081 while (pss->ch_list)
2082 ssh_destroy_channel(pss, pss->ch_list);
2083
2084 lws_chacha_destroy(&pss->active_keys_cts);
2085 lws_chacha_destroy(&pss->active_keys_stc);
2086
2087 p = &vhd->live_pss_list;
2088
2089 while (*p) {
2090 if ((*p) == pss) {
2091 *p = pss->next;
2092 continue;
2093 }
2094 p = &((*p)->next);
2095 }
2096 break;
2097
2098 case LWS_CALLBACK_RAW_RX:
2099 if (!pss)
2100 return -1;
2101 if (parse(pss, in, len))
2102 return -1;
2103 break;
2104
2105 case LWS_CALLBACK_RAW_WRITEABLE:
2106 if (!pss)
2107 break;
2108 n = 0;
2109 o = pss->write_task[pss->wt_tail];
2110 ch = pss->write_channel[pss->wt_tail];
2111
2112 if (pss->wt_head == pss->wt_tail)
2113 o = SSH_WT_NONE;
2114
2115 switch (o) {
2116 case SSH_WT_VERSION:
2117 if (!pss->vhd)
2118 break;
2119 n = lws_snprintf((char *)buf + LWS_PRE,
2120 sizeof(buf) - LWS_PRE - 1, "%s\r\n",
2121 pss->vhd->ops->server_string);
2122 write_task(pss, NULL, SSH_WT_OFFER);
2123 break;
2124
2125 case SSH_WT_OFFER:
2126 if (!pss->vhd)
2127 break;
2128 m = 0;
2129 n = offer(pss, buf + LWS_PRE,
2130 sizeof(buf) - LWS_PRE, 0, &m);
2131 if (n == 0) {
2132 lwsl_notice("Too small\n");
2133
2134 return -1;
2135 }
2136
2137 if (!pss->kex) {
2138 lwsl_notice("%s: SSH_WT_OFFER: pss->kex is NULL\n",
2139 __func__);
2140 return -1;
2141 }
2142
2143 /* we need a copy of it to generate the hash later */
2144 if (pss->kex->I_S)
2145 free(pss->kex->I_S);
2146 pss->kex->I_S = sshd_zalloc(m);
2147 if (!pss->kex->I_S) {
2148 lwsl_notice("OOM 5: %d\n", m);
2149
2150 return -1;
2151 }
2152 /* without length + padcount part */
2153 memcpy(pss->kex->I_S, buf + LWS_PRE + 5, m);
2154 pss->kex->I_S_payload_len = m; /* without padding */
2155 break;
2156
2157 case SSH_WT_OFFER_REPLY:
2158 memcpy(ps, pss->kex->kex_r, pss->kex->kex_r_len);
2159 n = pad_and_encrypt(&buf[LWS_PRE], ps,
2160 ps + pss->kex->kex_r_len, pss, 1);
2161 pss->kex_state = KEX_STATE_REPLIED_TO_OFFER;
2162 /* afterwards, must do newkeys */
2163 write_task(pss, NULL, SSH_WT_SEND_NEWKEYS);
2164 break;
2165
2166 case SSH_WT_SEND_NEWKEYS:
2167 pp = ps + 5;
2168 *pp++ = SSH_MSG_NEWKEYS;
2169 goto pac;
2170
2171 case SSH_WT_UA_ACCEPT:
2172 /*
2173 * If the server supports the service (and permits
2174 * the client to use it), it MUST respond with the
2175 * following:
2176 *
2177 * byte SSH_MSG_SERVICE_ACCEPT
2178 * string service name
2179 */
2180 pp = ps + 5;
2181 *pp++ = SSH_MSG_SERVICE_ACCEPT;
2182 lws_p32(pp, pss->npos);
2183 pp += 4;
2184 strcpy((char *)pp, pss->name);
2185 pp += pss->npos;
2186 goto pac;
2187
2188 case SSH_WT_UA_FAILURE:
2189 pp = ps + 5;
2190 *pp++ = SSH_MSG_USERAUTH_FAILURE;
2191 lws_p32(pp, 9);
2192 pp += 4;
2193 strcpy((char *)pp, "publickey");
2194 pp += 9;
2195 *pp++ = 0;
2196 goto pac;
2197
2198 case SSH_WT_UA_BANNER:
2199 pp = ps + 5;
2200 *pp++ = SSH_MSG_USERAUTH_BANNER;
2201 if (pss->vhd && pss->vhd->ops->banner)
2202 n = (int)pss->vhd->ops->banner((char *)&buf[650],
2203 150 - 1,
2204 lang, (int)sizeof(lang));
2205 lws_p32(pp, n);
2206 pp += 4;
2207 strcpy((char *)pp, (char *)&buf[650]);
2208 pp += n;
2209 if (lws_cstr(&pp, lang, sizeof(lang)))
2210 goto bail;
2211 goto pac;
2212
2213 case SSH_WT_UA_PK_OK:
2214 /*
2215 * The server MUST respond to this message with
2216 * either SSH_MSG_USERAUTH_FAILURE or with the
2217 * following:
2218 *
2219 * byte SSH_MSG_USERAUTH_PK_OK
2220 * string public key alg name from the request
2221 * string public key blob from the request
2222 */
2223 n = 74 + pss->ua->pubkey_len;
2224 if (n > (int)sizeof(buf) - LWS_PRE) {
2225 lwsl_notice("pubkey too large\n");
2226 goto bail;
2227 }
2228 ps1 = sshd_zalloc(n);
2229 if (!ps1)
2230 goto bail;
2231 ps = ps1;
2232 pp = ps1 + 5;
2233 *pp++ = SSH_MSG_USERAUTH_PK_OK;
2234 if (lws_cstr(&pp, pss->ua->alg, 64)) {
2235 free(ps1);
2236 goto bail;
2237 }
2238 lws_p32(pp, pss->ua->pubkey_len);
2239 pp += 4;
2240 memcpy(pp, pss->ua->pubkey, pss->ua->pubkey_len);
2241 pp += pss->ua->pubkey_len;
2242
2243 /* we no longer need the UA now we judged it */
2244 lws_ua_destroy(pss);
2245
2246 goto pac;
2247
2248 case SSH_WT_UA_SUCCESS:
2249 pp = ps + 5;
2250 *pp++ = SSH_MSG_USERAUTH_SUCCESS;
2251 /* end SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH */
2252 lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
2253 goto pac;
2254
2255 case SSH_WT_CH_OPEN_CONF:
2256 pp = ps + 5;
2257 *pp++ = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
2258 lws_p32(pp, pss->ch_temp->server_ch);
2259 pp += 4;
2260 lws_p32(pp, pss->ch_temp->sender_ch);
2261 pp += 4;
2262 /* tx initial window size towards us */
2263 lws_p32(pp, LWS_SSH_INITIAL_WINDOW);
2264 pp += 4;
2265 /* maximum packet size towards us */
2266 lws_p32(pp, 800);
2267 pp += 4;
2268 lwsl_info("SSH_WT_CH_OPEN_CONF\n");
2269 /* it's on the linked-list */
2270 pss->ch_temp = NULL;
2271 goto pac;
2272
2273 case SSH_WT_CH_FAILURE:
2274 pp = ps + 5;
2275 *pp++ = SSH_MSG_CHANNEL_OPEN_FAILURE;
2276 lws_p32(pp, ch->server_ch);
2277 pp += 4;
2278 lws_p32(pp, ch->sender_ch);
2279 pp += 4;
2280 lws_cstr(&pp, "reason", 64);
2281 lws_cstr(&pp, "en/US", 64);
2282 lwsl_info("SSH_WT_CH_FAILURE\n");
2283 goto pac;
2284
2285 case SSH_WT_CHRQ_SUCC:
2286 pp = ps + 5;
2287 *pp++ = SSH_MSG_CHANNEL_SUCCESS;
2288 lws_p32(pp, ch->server_ch);
2289 lwsl_info("SSH_WT_CHRQ_SUCC\n");
2290 pp += 4;
2291 goto pac;
2292
2293 case SSH_WT_CHRQ_FAILURE:
2294 pp = ps + 5;
2295 *pp++ = SSH_MSG_CHANNEL_FAILURE;
2296 lws_p32(pp, ch->server_ch);
2297 pp += 4;
2298 lwsl_info("SSH_WT_CHRQ_FAILURE\n");
2299 goto pac;
2300
2301 case SSH_WT_CH_CLOSE:
2302 pp = ps + 5;
2303 *pp++ = SSH_MSG_CHANNEL_CLOSE;
2304 lws_p32(pp, ch->server_ch);
2305 lwsl_info("SSH_WT_CH_CLOSE\n");
2306 pp += 4;
2307 goto pac;
2308
2309 case SSH_WT_CH_EOF:
2310 pp = ps + 5;
2311 *pp++ = SSH_MSG_CHANNEL_EOF;
2312 lws_p32(pp, ch->server_ch);
2313 lwsl_info("SSH_WT_CH_EOF\n");
2314 pp += 4;
2315 goto pac;
2316
2317 case SSH_WT_SCP_ACK_ERROR:
2318 case SSH_WT_SCP_ACK_OKAY:
2319 pp = ps + 5;
2320 *pp++ = SSH_MSG_CHANNEL_DATA;
2321 /* ps + 6 */
2322 lws_p32(pp, ch->sender_ch);
2323 pp += 4;
2324 lws_p32(pp, 1);
2325 pp += 4;
2326 if (o == SSH_WT_SCP_ACK_ERROR)
2327 *pp++ = 2;
2328 else
2329 *pp++ = 0;
2330 lwsl_info("SSH_WT_SCP_ACK_OKAY\n");
2331 goto pac;
2332
2333 case SSH_WT_WINDOW_ADJUST:
2334 pp = ps + 5;
2335 *pp++ = SSH_MSG_CHANNEL_WINDOW_ADJUST;
2336 /* ps + 6 */
2337 lws_p32(pp, ch->sender_ch);
2338 pp += 4;
2339 lws_p32(pp, 32768);
2340 pp += 4;
2341 lwsl_info("send SSH_MSG_CHANNEL_WINDOW_ADJUST\n");
2342 goto pac;
2343
2344 case SSH_WT_EXIT_STATUS:
2345 pp = ps + 5;
2346 *pp++ = SSH_MSG_CHANNEL_REQUEST;
2347 lws_p32(pp, ch->sender_ch);
2348 pp += 4;
2349 lws_p32(pp, 11);
2350 pp += 4;
2351 strcpy((char *)pp, "exit-status");
2352 pp += 11;
2353 *pp++ = 0;
2354 lws_p32(pp, ch->retcode);
2355 pp += 4;
2356 lwsl_info("send SSH_MSG_CHANNEL_EXIT_STATUS\n");
2357 goto pac;
2358
2359 case SSH_WT_NONE:
2360 default:
2361 /* sending payload */
2362
2363 ch = ssh_get_server_ch(pss, 0);
2364 /* have a channel up to send on? */
2365 if (!ch)
2366 break;
2367
2368 if (!pss->vhd || !pss->vhd->ops)
2369 break;
2370 n = pss->vhd->ops->tx_waiting(ch->priv);
2371 if (n < 0)
2372 return -1;
2373 if (!n)
2374 /* nothing to send */
2375 break;
2376
2377 if (n == (LWS_STDOUT | LWS_STDERR)) {
2378 /* pick one using round-robin */
2379 if (pss->serviced_stderr_last)
2380 n = LWS_STDOUT;
2381 else
2382 n = LWS_STDERR;
2383 }
2384
2385 pss->serviced_stderr_last = !!(n & LWS_STDERR);
2386
2387 /* stdout or stderr */
2388 pp = ps + 5;
2389 if (n == LWS_STDOUT)
2390 *pp++ = SSH_MSG_CHANNEL_DATA;
2391 else
2392 *pp++ = SSH_MSG_CHANNEL_EXTENDED_DATA;
2393 /* ps + 6 */
2394 lws_p32(pp, pss->ch_list->server_ch);
2395 m = 14;
2396 if (n == LWS_STDERR) {
2397 pp += 4;
2398 /* data type code... 1 for stderr payload */
2399 lws_p32(pp, SSH_EXTENDED_DATA_STDERR);
2400 m = 18;
2401 }
2402 /* also skip another strlen u32 at + 10 / +14 */
2403 pp += 8;
2404 /* ps + 14 / + 18 */
2405
2406 pp += pss->vhd->ops->tx(ch->priv, n, pp,
2407 &buf[sizeof(buf) - 1] - pp);
2408
2409 lws_p32(ps + m - 4, lws_ptr_diff(pp, (ps + m)));
2410
2411 if (pss->vhd->ops->tx_waiting(ch->priv) > 0)
2412 lws_callback_on_writable(wsi);
2413
2414 ch->window -= lws_ptr_diff(pp, ps) - m;
2415 //lwsl_debug("our send window: %d\n", ch->window);
2416
2417 /* fallthru */
2418 pac:
2419 if (!pss->vhd)
2420 break;
2421 n = pad_and_encrypt(&buf[LWS_PRE], ps, pp, pss, 0);
2422 break;
2423
2424 bail:
2425 lws_ua_destroy(pss);
2426 lws_kex_destroy(pss);
2427
2428 return 1;
2429
2430 }
2431
2432 if (n > 0) {
2433 m = lws_write(wsi, (unsigned char *)buf + LWS_PRE, n,
2434 LWS_WRITE_HTTP);
2435
2436 switch(o) {
2437 case SSH_WT_SEND_NEWKEYS:
2438 lwsl_info("Activating STC keys\n");
2439 pss->active_keys_stc = pss->kex->keys_next_stc;
2440 lws_chacha_activate(&pss->active_keys_stc);
2441 pss->kex_state = KEX_STATE_CRYPTO_INITIALIZED;
2442 pss->kex->newkeys |= 1;
2443 if (pss->kex->newkeys == 3)
2444 lws_kex_destroy(pss);
2445 break;
2446 case SSH_WT_UA_PK_OK:
2447 free(ps1);
2448 break;
2449 case SSH_WT_CH_CLOSE:
2450 if (ch->received_close) {
2451 /*
2452 * We are sending this at the behest of
2453 * the remote peer...
2454 * we can destroy the channel with no
2455 * further communication.
2456 */
2457 ssh_destroy_channel(pss, ch);
2458 break;
2459 }
2460 ch->sent_close = 1;
2461 break;
2462 }
2463 if (m < 0) {
2464 lwsl_err("ERR %d from write\n", m);
2465 goto bail;
2466 }
2467
2468 if (o != SSH_WT_VERSION)
2469 pss->ssh_sequence_ctr_stc++;
2470
2471 if (o != SSH_WT_NONE)
2472 pss->wt_tail =
2473 (pss->wt_tail + 1) & 7;
2474 } else
2475 if (o == SSH_WT_UA_PK_OK) /* free it either way */
2476 free(ps1);
2477
2478 ch = ssh_get_server_ch(pss, 0);
2479
2480 if (pss->wt_head != pss->wt_tail ||
2481 (ch && ch->priv && pss->vhd &&
2482 pss->vhd->ops->tx_waiting(ch->priv)))
2483 lws_callback_on_writable(wsi);
2484
2485 break;
2486
2487 case LWS_CALLBACK_SSH_UART_SET_RXFLOW:
2488 /*
2489 * this is sent to set rxflow state on any connections that
2490 * sink on a particular sink. The sink index affected is in len
2491 *
2492 * More than one protocol may sink to the same uart, and the
2493 * protocol may select the sink itself, eg, in the URL used
2494 * to set up the connection.
2495 */
2496 lwsl_notice("sshd LWS_CALLBACK_SSH_UART_SET_RXFLOW: wsi %p, %d\n",
2497 wsi, (int)len & 1);
2498 lws_rx_flow_control(wsi, len & 1);
2499 break;
2500
2501 case LWS_CALLBACK_CGI:
2502 if (!pss)
2503 break;
2504 if (pss->vhd && pss->vhd->ops &&
2505 pss->vhd->ops->child_process_io &&
2506 pss->vhd->ops->child_process_io(pss->ch_temp->priv,
2507 pss->wsi, (struct lws_cgi_args *)in))
2508 return -1;
2509 break;
2510
2511 case LWS_CALLBACK_CGI_PROCESS_ATTACH:
2512 if (!pss)
2513 break;
2514 ch = ssh_get_server_ch(pss, pss->channel_doing_spawn);
2515 if (ch) {
2516 ch->spawn_pid = (int)len; /* child process PID */
2517 lwsl_notice("associated PID %d to ch %d\n", (int)len,
2518 pss->channel_doing_spawn);
2519 }
2520 break;
2521
2522 case LWS_CALLBACK_CGI_TERMINATED:
2523 if (!pss)
2524 break;
2525 if (pss->vhd && pss->vhd->ops &&
2526 pss->vhd->ops->child_process_terminated)
2527 pss->vhd->ops->child_process_terminated(pss->ch_temp->priv,
2528 pss->wsi);
2529 /*
2530 * we have the child PID in len... we need to match it to a
2531 * channel that is on the wsi
2532 */
2533 ch = pss->ch_list;
2534
2535 while (ch) {
2536 if (ch->spawn_pid == len) {
2537 lwsl_notice("starting close of ch with PID %d\n",
2538 (int)len);
2539 ch->scheduled_close = 1;
2540 write_task(pss, ch, SSH_WT_CH_CLOSE);
2541 break;
2542 }
2543 ch = ch->next;
2544 }
2545 break;
2546
2547 default:
2548 break;
2549 }
2550
2551 return 0;
2552 }
2553
2554 #define LWS_PLUGIN_PROTOCOL_LWS_RAW_SSHD { \
2555 "lws-ssh-base", \
2556 lws_callback_raw_sshd, \
2557 sizeof(struct per_session_data__sshd), \
2558 1024, 0, NULL, 900 \
2559 }
2560
2561 const struct lws_protocols protocols_sshd[] = {
2562 LWS_PLUGIN_PROTOCOL_LWS_RAW_SSHD,
2563 { NULL, NULL, 0, 0, 0, NULL, 0 } /* terminator */
2564 };
2565
2566 #if !defined (LWS_PLUGIN_STATIC)
2567
2568 LWS_VISIBLE int
init_protocol_lws_ssh_base(struct lws_context * context,struct lws_plugin_capability * c)2569 init_protocol_lws_ssh_base(struct lws_context *context,
2570 struct lws_plugin_capability *c)
2571 {
2572 if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
2573 lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
2574 c->api_magic);
2575 return 1;
2576 }
2577
2578 c->protocols = protocols_sshd;
2579 c->count_protocols = LWS_ARRAY_SIZE(protocols_sshd);
2580 c->extensions = NULL;
2581 c->count_extensions = 0;
2582
2583 return 0;
2584 }
2585
2586 LWS_VISIBLE int
destroy_protocol_lws_ssh_base(struct lws_context * context)2587 destroy_protocol_lws_ssh_base(struct lws_context *context)
2588 {
2589 return 0;
2590 }
2591 #endif
2592