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