ssh
Embed:
(wiki syntax)
Show/hide line numbers
ssh.c
00001 /* ssh.c 00002 * 00003 * Copyright (C) 2014-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSH. 00006 * 00007 * wolfSSH is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSH is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with wolfSSH. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 00022 /* 00023 * The ssh module contains the public API for wolfSSH. 00024 */ 00025 00026 00027 #ifdef HAVE_CONFIG_H 00028 #include <config.h> 00029 #endif 00030 00031 #include <wolfssh/ssh.h> 00032 #include <wolfssh/internal.h> 00033 #include <wolfssh/log.h> 00034 #include <wolfcrypt/wc_port.h> 00035 //#include "esp_log.h" 00036 00037 #ifdef NO_INLINE 00038 #include <wolfssh/misc.h> 00039 #else 00040 #define WOLFSSH_MISC_INCLUDED 00041 #include "src/misc.c" 00042 #endif 00043 00044 00045 int wolfSSH_Init(void) 00046 { 00047 int ret = WS_SUCCESS; 00048 00049 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_Init()"); 00050 if (wolfCrypt_Init() != 0) 00051 ret = WS_CRYPTO_FAILED; 00052 00053 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_Init(), returning %d", ret); 00054 return ret; 00055 } 00056 00057 00058 int wolfSSH_Cleanup(void) 00059 { 00060 int ret = WS_SUCCESS; 00061 00062 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_Cleanup()"); 00063 00064 if (wolfCrypt_Cleanup() != 0) 00065 ret = WS_CRYPTO_FAILED; 00066 00067 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_Cleanup(), returning %d", ret); 00068 return ret; 00069 } 00070 00071 00072 WOLFSSH_CTX* wolfSSH_CTX_new(byte side, void* heap) 00073 { 00074 WOLFSSH_CTX* ctx; 00075 00076 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_new()"); 00077 00078 if (side != WOLFSSH_ENDPOINT_SERVER && side != WOLFSSH_ENDPOINT_CLIENT) { 00079 WLOG(WS_LOG_DEBUG, "Invalid endpoint type"); 00080 return NULL; 00081 } 00082 00083 ctx = (WOLFSSH_CTX*)WMALLOC(sizeof(WOLFSSH_CTX), heap, DYNTYPE_CTX); 00084 ctx = CtxInit(ctx, side, heap); 00085 00086 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CTX_new(), ctx = %p", ctx); 00087 00088 return ctx; 00089 } 00090 00091 00092 void wolfSSH_CTX_free(WOLFSSH_CTX* ctx) 00093 { 00094 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_free()"); 00095 00096 if (ctx) { 00097 CtxResourceFree(ctx); 00098 WFREE(ctx, ctx->heap, DYNTYPE_CTX); 00099 } 00100 } 00101 00102 00103 WOLFSSH* wolfSSH_new(WOLFSSH_CTX* ctx) 00104 { 00105 WOLFSSH* ssh; 00106 void* heap = NULL; 00107 00108 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_new()"); 00109 //ESP_LOGI("WOLFSSH", "Entering wolfSSH_new()"); 00110 00111 if (ctx) 00112 heap = ctx->heap; 00113 else { 00114 WLOG(WS_LOG_ERROR, "Trying to init a wolfSSH w/o wolfSSH_CTX"); 00115 return NULL; 00116 } 00117 00118 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_new()"); 00119 //ESP_LOGI("WOLFSSH", "ctx check ok, now malloc WOLFSSH"); 00120 00121 ssh = (WOLFSSH*)WMALLOC(sizeof(WOLFSSH), heap, DYNTYPE_SSH); 00122 //ESP_LOGI("WOLFSSH", "malloc done, SSH Initialization..."); 00123 //if(ssh == NULL) ESP_LOGE("WOLFSSH", "ssh is NULL, passing to SshInit() anyway..."); 00124 ssh = SshInit(ssh, ctx); 00125 //ESP_LOGI("WOLFSSH", "SshInit OK"); 00126 //if(ssh == NULL) ESP_LOGE("WOLFSSH", "ssh is NULL after SshInit()"); 00127 00128 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_new(), ssh = %p", ssh); 00129 //ESP_LOGI("WOLFSSH", "Leaving wolfSSH_new()"); 00130 00131 return ssh; 00132 } 00133 00134 00135 void wolfSSH_free(WOLFSSH* ssh) 00136 { 00137 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_free()"); 00138 00139 if (ssh) { 00140 void* heap = ssh->ctx ? ssh->ctx->heap : NULL; 00141 SshResourceFree(ssh, heap); 00142 WFREE(ssh, heap, DYNTYPE_SSH); 00143 } 00144 } 00145 00146 00147 int wolfSSH_set_fd(WOLFSSH* ssh, int fd) 00148 { 00149 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_set_fd()"); 00150 00151 if (ssh) { 00152 ssh->rfd = fd; 00153 ssh->wfd = fd; 00154 00155 ssh->ioReadCtx = &ssh->rfd; 00156 ssh->ioWriteCtx = &ssh->wfd; 00157 00158 return WS_SUCCESS; 00159 } 00160 return WS_BAD_ARGUMENT; 00161 } 00162 00163 00164 int wolfSSH_get_fd(const WOLFSSH* ssh) 00165 { 00166 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_get_fd()"); 00167 00168 if (ssh) 00169 return ssh->rfd; 00170 00171 return WS_BAD_ARGUMENT; 00172 } 00173 00174 00175 int wolfSSH_SetHighwater(WOLFSSH* ssh, word32 highwater) 00176 { 00177 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetHighwater()"); 00178 00179 if (ssh) { 00180 ssh->highwaterMark = highwater; 00181 00182 return WS_SUCCESS; 00183 } 00184 00185 return WS_BAD_ARGUMENT; 00186 } 00187 00188 00189 word32 wolfSSH_GetHighwater(WOLFSSH* ssh) 00190 { 00191 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_GetHighwater()"); 00192 00193 if (ssh) 00194 return ssh->highwaterMark; 00195 00196 return 0; 00197 } 00198 00199 00200 void wolfSSH_SetHighwaterCb(WOLFSSH_CTX* ctx, word32 highwater, 00201 WS_CallbackHighwater cb) 00202 { 00203 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetHighwaterCb()"); 00204 00205 if (ctx) { 00206 ctx->highwaterMark = highwater; 00207 ctx->highwaterCb = cb; 00208 } 00209 } 00210 00211 00212 void wolfSSH_SetHighwaterCtx(WOLFSSH* ssh, void* ctx) 00213 { 00214 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetHighwaterCtx()"); 00215 00216 if (ssh) 00217 ssh->highwaterCtx = ctx; 00218 } 00219 00220 00221 void* wolfSSH_GetHighwaterCtx(WOLFSSH* ssh) 00222 { 00223 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_GetHighwaterCtx()"); 00224 00225 if (ssh) 00226 return ssh->highwaterCtx; 00227 00228 return NULL; 00229 } 00230 00231 00232 int wolfSSH_get_error(const WOLFSSH* ssh) 00233 { 00234 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_get_error()"); 00235 00236 if (ssh) 00237 return ssh->error; 00238 00239 return WS_BAD_ARGUMENT; 00240 } 00241 00242 00243 const char* wolfSSH_get_error_name(const WOLFSSH* ssh) 00244 { 00245 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_get_error_name()"); 00246 00247 if (ssh) 00248 return GetErrorString(ssh->error); 00249 00250 return NULL; 00251 } 00252 00253 00254 const char acceptError[] = "accept error: %s, %d"; 00255 const char acceptState[] = "accept state: %s"; 00256 00257 00258 int wolfSSH_accept(WOLFSSH* ssh) 00259 { 00260 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_accept()"); 00261 //ESP_LOGI("WOLFSSH", "Entering wolfSSH_accept()"); 00262 00263 if (ssh == NULL) 00264 return WS_BAD_ARGUMENT; 00265 00266 //ESP_LOGI("WOLFSSH", "ssh is not NULL"); 00267 00268 switch (ssh->acceptState) { 00269 00270 case ACCEPT_BEGIN: 00271 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_BEGIN"); 00272 if ( (ssh->error = SendProtoId(ssh)) < WS_SUCCESS) { 00273 while(ssh->error == WS_WANT_READ) { 00274 // non-blocking tcp 00275 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00276 ssh->error = DoReceive(ssh); 00277 } 00278 if(ssh->error == WS_SUCCESS) break; 00279 WLOG(WS_LOG_DEBUG, acceptError, "BEGIN", ssh->error); 00280 return WS_FATAL_ERROR; 00281 } 00282 ssh->acceptState = ACCEPT_SERVER_VERSION_SENT; 00283 WLOG(WS_LOG_DEBUG, acceptState, "SERVER_VERSION_SENT"); 00284 FALL_THROUGH; 00285 00286 case ACCEPT_SERVER_VERSION_SENT: 00287 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_SERVER_VERSION_SENT"); 00288 while (ssh->clientState < CLIENT_VERSION_DONE) { 00289 if ( (ssh->error = DoProtoId(ssh)) < WS_SUCCESS) { 00290 while(ssh->error == WS_WANT_READ) { 00291 // non-blocking tcp 00292 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00293 ssh->error = DoReceive(ssh); 00294 } 00295 if(ssh->error == WS_SUCCESS) break; 00296 WLOG(WS_LOG_DEBUG, acceptError, 00297 "SERVER_VERSION_SENT", ssh->error); 00298 return WS_FATAL_ERROR; 00299 } 00300 } 00301 ssh->acceptState = ACCEPT_CLIENT_VERSION_DONE; 00302 WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_VERSION_DONE"); 00303 FALL_THROUGH; 00304 00305 case ACCEPT_CLIENT_VERSION_DONE: 00306 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_CLIENT_VERSION_DONE"); 00307 if ( (ssh->error = SendKexInit(ssh)) < WS_SUCCESS) { 00308 while(ssh->error == WS_WANT_READ) { 00309 // non-blocking tcp 00310 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00311 ssh->error = DoReceive(ssh); 00312 } 00313 if(ssh->error == WS_SUCCESS) break; 00314 WLOG(WS_LOG_DEBUG, acceptError, 00315 "CLIENT_VERSION_DONE", ssh->error); 00316 return WS_FATAL_ERROR; 00317 } 00318 ssh->acceptState = ACCEPT_SERVER_KEXINIT_SENT; 00319 WLOG(WS_LOG_DEBUG, acceptState, "SERVER_KEXINIT_SENT"); 00320 FALL_THROUGH; 00321 00322 case ACCEPT_SERVER_KEXINIT_SENT: 00323 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_SERVER_KEXINIT_SENT"); 00324 while (ssh->isKeying) { 00325 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00326 while(ssh->error == WS_WANT_READ) { 00327 // non-blocking tcp 00328 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00329 ssh->error = DoReceive(ssh); 00330 } 00331 if(ssh->error == WS_SUCCESS) break; 00332 WLOG(WS_LOG_DEBUG, acceptError, 00333 "SERVER_KEXINIT_SENT", ssh->error); 00334 //ESP_LOGE("WOLFSSH", "Accept error: SERVER_KEXINIT_SENT, %d", ssh->error); 00335 return WS_FATAL_ERROR; 00336 } 00337 } 00338 ssh->acceptState = ACCEPT_KEYED; 00339 WLOG(WS_LOG_DEBUG, acceptState, "KEYED"); 00340 FALL_THROUGH; 00341 00342 case ACCEPT_KEYED: 00343 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_KEYED"); 00344 while (ssh->clientState < CLIENT_USERAUTH_REQUEST_DONE) { 00345 if ( (ssh->error = DoReceive(ssh)) < 0) { 00346 while(ssh->error == WS_WANT_READ) { 00347 // non-blocking tcp 00348 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00349 ssh->error = DoReceive(ssh); 00350 } 00351 if(ssh->error == WS_SUCCESS) break; 00352 WLOG(WS_LOG_DEBUG, acceptError, 00353 "KEYED", ssh->error); 00354 return WS_FATAL_ERROR; 00355 } 00356 } 00357 ssh->acceptState = ACCEPT_CLIENT_USERAUTH_REQUEST_DONE; 00358 WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_USERAUTH_REQUEST_DONE"); 00359 FALL_THROUGH; 00360 00361 case ACCEPT_CLIENT_USERAUTH_REQUEST_DONE: 00362 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_CLIENT_USERAUTH_REQUEST_DONE"); 00363 if ( (ssh->error = SendServiceAccept(ssh, ID_SERVICE_USERAUTH)) < 00364 WS_SUCCESS) { 00365 WLOG(WS_LOG_DEBUG, acceptError, 00366 "CLIENT_USERAUTH_REQUEST_DONE", ssh->error); 00367 return WS_FATAL_ERROR; 00368 } 00369 ssh->acceptState = ACCEPT_SERVER_USERAUTH_ACCEPT_SENT; 00370 WLOG(WS_LOG_DEBUG, acceptState, 00371 "ACCEPT_SERVER_USERAUTH_ACCEPT_SENT"); 00372 FALL_THROUGH; 00373 00374 case ACCEPT_SERVER_USERAUTH_ACCEPT_SENT: 00375 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_SERVER_USERAUTH_ACCEPT_SENT"); 00376 while (ssh->clientState < CLIENT_USERAUTH_DONE) { 00377 if ( (ssh->error = DoReceive(ssh)) < 0) { 00378 while(ssh->error == WS_WANT_READ) { 00379 // non-blocking tcp 00380 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00381 ssh->error = DoReceive(ssh); 00382 } 00383 if(ssh->error == WS_SUCCESS) break; 00384 WLOG(WS_LOG_DEBUG, acceptError, 00385 "SERVER_USERAUTH_ACCEPT_SENT", ssh->error); 00386 return WS_FATAL_ERROR; 00387 } 00388 } 00389 ssh->acceptState = ACCEPT_CLIENT_USERAUTH_DONE; 00390 WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_USERAUTH_DONE"); 00391 FALL_THROUGH; 00392 00393 case ACCEPT_CLIENT_USERAUTH_DONE: 00394 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_CLIENT_USERAUTH_DONE"); 00395 if ( (ssh->error = SendUserAuthSuccess(ssh)) < WS_SUCCESS) { 00396 WLOG(WS_LOG_DEBUG, acceptError, 00397 "CLIENT_USERAUTH_DONE", ssh->error); 00398 return WS_FATAL_ERROR; 00399 } 00400 ssh->acceptState = ACCEPT_SERVER_USERAUTH_SENT; 00401 WLOG(WS_LOG_DEBUG, acceptState, "SERVER_USERAUTH_SENT"); 00402 FALL_THROUGH; 00403 00404 case ACCEPT_SERVER_USERAUTH_SENT: 00405 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_SERVER_USERAUTH_SENT"); 00406 while (ssh->clientState < CLIENT_DONE) { 00407 if ( (ssh->error = DoReceive(ssh)) < 0) { 00408 while(ssh->error == WS_WANT_READ) { 00409 // non-blocking tcp 00410 //ESP_LOGW("WOLFSSH", "WANT_READ: looping"); 00411 ssh->error = DoReceive(ssh); 00412 } 00413 if(ssh->error == WS_SUCCESS) break; 00414 WLOG(WS_LOG_DEBUG, acceptError, 00415 "SERVER_USERAUTH_SENT", ssh->error); 00416 return WS_FATAL_ERROR; 00417 } 00418 } 00419 ssh->acceptState = ACCEPT_CLIENT_CHANNEL_REQUEST_DONE; 00420 WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_CHANNEL_REQUEST_DONE"); 00421 FALL_THROUGH; 00422 00423 case ACCEPT_CLIENT_CHANNEL_REQUEST_DONE: 00424 //ESP_LOGI("WOLFSSH", "acceptState = ACCEPT_CLIENT_CHANNEL_REQUEST_DONE"); 00425 if ( (ssh->error = SendChannelOpenConf(ssh)) < WS_SUCCESS) { 00426 WLOG(WS_LOG_DEBUG, acceptError, 00427 "CLIENT_CHANNEL_REQUEST_DONE", ssh->error); 00428 //ESP_LOGE("WOLFSSH", "SendChannelOpenConf failed: %d", ssh->error); 00429 return WS_FATAL_ERROR; 00430 } 00431 ssh->acceptState = ACCEPT_SERVER_CHANNEL_ACCEPT_SENT; 00432 WLOG(WS_LOG_DEBUG, acceptState, "SERVER_CHANNEL_ACCEPT_SENT"); 00433 } 00434 00435 return WS_SUCCESS; 00436 } 00437 00438 00439 const char connectError[] = "connect error: %s, %d"; 00440 const char connectState[] = "connect state: %s"; 00441 00442 00443 int wolfSSH_connect(WOLFSSH* ssh) 00444 { 00445 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_connect()"); 00446 00447 if (ssh == NULL) 00448 return WS_BAD_ARGUMENT; 00449 00450 switch (ssh->connectState) { 00451 00452 case CONNECT_BEGIN: 00453 if ( (ssh->error = SendProtoId(ssh)) < WS_SUCCESS) { 00454 WLOG(WS_LOG_DEBUG, connectError, "BEGIN", ssh->error); 00455 return WS_FATAL_ERROR; 00456 } 00457 ssh->connectState = CONNECT_CLIENT_VERSION_SENT; 00458 WLOG(WS_LOG_DEBUG, connectState, "CLIENT_VERSION_SENT"); 00459 FALL_THROUGH; 00460 00461 case CONNECT_CLIENT_VERSION_SENT: 00462 while (ssh->serverState < SERVER_VERSION_DONE) { 00463 if ( (ssh->error = DoProtoId(ssh)) < WS_SUCCESS) { 00464 WLOG(WS_LOG_DEBUG, connectError, 00465 "CLIENT_VERSION_SENT", ssh->error); 00466 return WS_FATAL_ERROR; 00467 } 00468 } 00469 ssh->connectState = CONNECT_SERVER_VERSION_DONE; 00470 WLOG(WS_LOG_DEBUG, connectState, "SERVER_VERSION_DONE"); 00471 FALL_THROUGH; 00472 00473 case CONNECT_SERVER_VERSION_DONE: 00474 if ( (ssh->error = SendKexInit(ssh)) < WS_SUCCESS) { 00475 WLOG(WS_LOG_DEBUG, acceptError, 00476 "SERVER_VERSION_DONE", ssh->error); 00477 return WS_FATAL_ERROR; 00478 } 00479 ssh->connectState = CONNECT_CLIENT_KEXINIT_SENT; 00480 WLOG(WS_LOG_DEBUG, connectState, "CLIENT_KEXINIT_SENT"); 00481 FALL_THROUGH; 00482 00483 case CONNECT_CLIENT_KEXINIT_SENT: 00484 while (ssh->serverState < SERVER_KEXINIT_DONE) { 00485 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00486 WLOG(WS_LOG_DEBUG, connectError, 00487 "CLIENT_KEXINIT_SENT", ssh->error); 00488 return WS_FATAL_ERROR; 00489 } 00490 } 00491 ssh->connectState = CONNECT_SERVER_KEXINIT_DONE; 00492 WLOG(WS_LOG_DEBUG, connectState, "SERVER_KEXINIT_DONE"); 00493 FALL_THROUGH; 00494 00495 case CONNECT_SERVER_KEXINIT_DONE: 00496 if (ssh->handshake->kexId == ID_DH_GEX_SHA256) 00497 ssh->error = SendKexDhGexRequest(ssh); 00498 else 00499 ssh->error = SendKexDhInit(ssh); 00500 if (ssh->error < WS_SUCCESS) { 00501 WLOG(WS_LOG_DEBUG, connectError, 00502 "SERVER_KEXINIT_DONE", ssh->error); 00503 return WS_FATAL_ERROR; 00504 } 00505 ssh->connectState = CONNECT_CLIENT_KEXDH_INIT_SENT; 00506 WLOG(WS_LOG_DEBUG, connectState, "CLIENT_KEXDH_INIT_SENT"); 00507 FALL_THROUGH; 00508 00509 case CONNECT_CLIENT_KEXDH_INIT_SENT: 00510 while (ssh->isKeying) { 00511 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00512 WLOG(WS_LOG_DEBUG, connectError, 00513 "CLIENT_KEXDH_INIT_SENT", ssh->error); 00514 return WS_FATAL_ERROR; 00515 } 00516 } 00517 ssh->connectState = CONNECT_KEYED; 00518 WLOG(WS_LOG_DEBUG, connectState, "KEYED"); 00519 FALL_THROUGH; 00520 00521 case CONNECT_KEYED: 00522 if ( (ssh->error = SendServiceRequest(ssh, ID_SERVICE_USERAUTH)) < 00523 WS_SUCCESS) { 00524 WLOG(WS_LOG_DEBUG, connectError, "KEYED", ssh->error); 00525 return WS_FATAL_ERROR; 00526 } 00527 ssh->connectState = CONNECT_CLIENT_USERAUTH_REQUEST_SENT; 00528 WLOG(WS_LOG_DEBUG, connectState, "CLIENT_USERAUTH_REQUEST_SENT"); 00529 FALL_THROUGH; 00530 00531 case CONNECT_CLIENT_USERAUTH_REQUEST_SENT: 00532 while (ssh->serverState < SERVER_USERAUTH_REQUEST_DONE) { 00533 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00534 WLOG(WS_LOG_DEBUG, connectError, 00535 "CLIENT_USERAUTH_REQUEST_SENT", ssh->error); 00536 return WS_FATAL_ERROR; 00537 } 00538 } 00539 ssh->connectState = CONNECT_SERVER_USERAUTH_REQUEST_DONE; 00540 WLOG(WS_LOG_DEBUG, connectState, "SERVER_USERAUTH_REQUEST_DONE"); 00541 FALL_THROUGH; 00542 00543 case CONNECT_SERVER_USERAUTH_REQUEST_DONE: 00544 if ( (ssh->error = SendUserAuthRequest(ssh, ID_NONE)) < 00545 WS_SUCCESS) { 00546 WLOG(WS_LOG_DEBUG, connectError, 00547 "SERVER_USERAUTH_REQUEST_DONE", ssh->error); 00548 return WS_FATAL_ERROR; 00549 } 00550 ssh->connectState = CONNECT_CLIENT_USERAUTH_SENT; 00551 WLOG(WS_LOG_DEBUG, connectState, "CLIENT_USERAUTH_SENT"); 00552 FALL_THROUGH; 00553 00554 case CONNECT_CLIENT_USERAUTH_SENT: 00555 while (ssh->serverState < SERVER_USERAUTH_ACCEPT_DONE) { 00556 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00557 WLOG(WS_LOG_DEBUG, connectError, 00558 "CLIENT_USERAUTH_SENT", ssh->error); 00559 return WS_FATAL_ERROR; 00560 } 00561 } 00562 ssh->connectState = CONNECT_SERVER_USERAUTH_ACCEPT_DONE; 00563 WLOG(WS_LOG_DEBUG, connectState, "SERVER_USERAUTH_ACCEPT_DONE"); 00564 FALL_THROUGH; 00565 00566 case CONNECT_SERVER_USERAUTH_ACCEPT_DONE: 00567 if ( (ssh->error = SendChannelOpenSession(ssh, DEFAULT_WINDOW_SZ, 00568 DEFAULT_MAX_PACKET_SZ)) < WS_SUCCESS) { 00569 WLOG(WS_LOG_DEBUG, connectError, 00570 "SERVER_USERAUTH_ACCEPT_DONE", ssh->error); 00571 return WS_FATAL_ERROR; 00572 } 00573 ssh->connectState = CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT; 00574 WLOG(WS_LOG_DEBUG, connectState, 00575 "CLIENT_CHANNEL_OPEN_SESSION_SENT"); 00576 FALL_THROUGH; 00577 00578 case CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT: 00579 while (ssh->serverState < SERVER_CHANNEL_OPEN_DONE) { 00580 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00581 WLOG(WS_LOG_DEBUG, connectError, 00582 "CLIENT_CHANNEL_OPEN_SESSION_SENT", ssh->error); 00583 return WS_FATAL_ERROR; 00584 } 00585 } 00586 ssh->connectState = CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE; 00587 WLOG(WS_LOG_DEBUG, connectState, 00588 "SERVER_CHANNEL_OPEN_SESSION_DONE"); 00589 FALL_THROUGH; 00590 00591 case CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE: 00592 if ( (ssh->error = SendChannelRequestShell(ssh)) < WS_SUCCESS) { 00593 WLOG(WS_LOG_DEBUG, connectError, 00594 "SERVER_CHANNEL_OPEN_SESSION_DONE", ssh->error); 00595 return WS_FATAL_ERROR; 00596 } 00597 ssh->connectState = CONNECT_CLIENT_CHANNEL_REQUEST_SHELL_SENT; 00598 WLOG(WS_LOG_DEBUG, connectState, 00599 "CLIENT_CHANNEL_REQUEST_SHELL_SENT"); 00600 FALL_THROUGH; 00601 00602 case CONNECT_CLIENT_CHANNEL_REQUEST_SHELL_SENT: 00603 while (ssh->serverState < SERVER_DONE) { 00604 if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { 00605 WLOG(WS_LOG_DEBUG, connectError, 00606 "CLIENT_CHANNEL_REQUEST_SHELL_SENT", ssh->error); 00607 return WS_FATAL_ERROR; 00608 } 00609 } 00610 ssh->connectState = CONNECT_SERVER_CHANNEL_REQUEST_SHELL_DONE; 00611 WLOG(WS_LOG_DEBUG, connectState, 00612 "SERVER_CHANNEL_REQUEST_SHELL_DONE"); 00613 } 00614 00615 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_connect()"); 00616 return WS_SUCCESS; 00617 } 00618 00619 00620 int wolfSSH_shutdown(WOLFSSH* ssh) 00621 { 00622 int ret = WS_SUCCESS; 00623 00624 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_shutdown()"); 00625 00626 if (ssh == NULL) 00627 ret = WS_BAD_ARGUMENT; 00628 00629 if (ret == WS_SUCCESS) 00630 ret = SendChannelEof(ssh, 0); 00631 00632 if (ret == WS_SUCCESS) 00633 ret = SendChannelClose(ssh, 0); 00634 00635 if (ret == WS_SUCCESS) 00636 ret = SendDisconnect(ssh, WOLFSSH_DISCONNECT_BY_APPLICATION); 00637 00638 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_shutdown(), ret = %d", ret); 00639 return ret; 00640 } 00641 00642 00643 int wolfSSH_TriggerKeyExchange(WOLFSSH* ssh) 00644 { 00645 int ret = WS_SUCCESS; 00646 00647 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_TriggerKeyExchange()"); 00648 if (ssh == NULL) 00649 ret = WS_BAD_ARGUMENT; 00650 00651 if (ret == WS_SUCCESS) 00652 ret = SendKexInit(ssh); 00653 00654 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_TriggerKeyExchange(), ret = %d", ret); 00655 return ret; 00656 } 00657 00658 00659 int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz) 00660 { 00661 Buffer* inputBuffer; 00662 00663 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_stream_read()"); 00664 //ESP_LOGI("WOLFSSH", "wolfSSH_stream_read()"); 00665 00666 if (ssh == NULL || buf == NULL || bufSz == 0 || ssh->channelList == NULL) 00667 return WS_BAD_ARGUMENT; 00668 00669 inputBuffer = &ssh->channelList->inputBuffer; 00670 00671 while (inputBuffer->length - inputBuffer->idx == 0) { 00672 int ret = DoReceive(ssh); 00673 if (ret < 0) { 00674 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_stream_read(), ret = %d", ret); 00675 return ret; 00676 } 00677 } 00678 //ESP_LOGI("WOLFSSH", "wolfSSH_stream_read: while loop done"); 00679 00680 bufSz = min(bufSz, inputBuffer->length - inputBuffer->idx); 00681 WMEMCPY(buf, inputBuffer->buffer + inputBuffer->idx, bufSz); 00682 inputBuffer->idx += bufSz; 00683 00684 if (!ssh->isKeying && (inputBuffer->length > inputBuffer->bufferSz / 2)) { 00685 00686 word32 usedSz = inputBuffer->length - inputBuffer->idx; 00687 word32 bytesToAdd = inputBuffer->idx; 00688 int sendResult; 00689 00690 WLOG(WS_LOG_DEBUG, "Making more room: %u", usedSz); 00691 if (usedSz) { 00692 WLOG(WS_LOG_DEBUG, " ...moving data down"); 00693 WMEMMOVE(inputBuffer->buffer, 00694 inputBuffer->buffer + bytesToAdd, usedSz); 00695 } 00696 00697 sendResult = SendChannelWindowAdjust(ssh, 00698 ssh->channelList->peerChannel, 00699 bytesToAdd); 00700 if (sendResult != WS_SUCCESS) 00701 bufSz = sendResult; 00702 00703 WLOG(WS_LOG_INFO, " bytesToAdd = %u", bytesToAdd); 00704 WLOG(WS_LOG_INFO, " windowSz = %u", ssh->channelList->windowSz); 00705 ssh->channelList->windowSz += bytesToAdd; 00706 WLOG(WS_LOG_INFO, " update windowSz = %u", ssh->channelList->windowSz); 00707 00708 inputBuffer->length = usedSz; 00709 inputBuffer->idx = 0; 00710 } 00711 00712 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_stream_read(), rxd = %d", bufSz); 00713 return bufSz; 00714 } 00715 00716 00717 int wolfSSH_stream_send(WOLFSSH* ssh, byte* buf, word32 bufSz) 00718 { 00719 int bytesTxd = 0; 00720 00721 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_stream_send()"); 00722 00723 if (ssh == NULL || buf == NULL || ssh->channelList == NULL) 00724 return WS_BAD_ARGUMENT; 00725 00726 bytesTxd = SendChannelData(ssh, ssh->channelList->peerChannel, buf, bufSz); 00727 00728 WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_stream_send(), txd = %d", bytesTxd); 00729 return bytesTxd; 00730 } 00731 00732 00733 void wolfSSH_SetUserAuth(WOLFSSH_CTX* ctx, WS_CallbackUserAuth cb) 00734 { 00735 if (ctx != NULL) { 00736 ctx->userAuthCb = cb; 00737 } 00738 } 00739 00740 00741 void wolfSSH_SetUserAuthCtx(WOLFSSH* ssh, void* userAuthCtx) 00742 { 00743 if (ssh != NULL) { 00744 ssh->userAuthCtx = userAuthCtx; 00745 } 00746 } 00747 00748 00749 void* wolfSSH_GetUserAuthCtx(WOLFSSH* ssh) 00750 { 00751 if (ssh != NULL) { 00752 return ssh->userAuthCtx; 00753 } 00754 return NULL; 00755 } 00756 00757 00758 int wolfSSH_SetUsername(WOLFSSH* ssh, const char* username) 00759 { 00760 char* value = NULL; 00761 word32 valueSz; 00762 int ret = WS_SUCCESS; 00763 00764 if (ssh == NULL || ssh->handshake == NULL || 00765 ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER || 00766 username == NULL) { 00767 00768 ret = WS_BAD_ARGUMENT; 00769 } 00770 00771 if (ret == WS_SUCCESS) { 00772 valueSz = (word32)WSTRLEN(username); 00773 if (valueSz > 0) 00774 value = (char*)WMALLOC(valueSz + 1, ssh->ctx->heap, DYNTYPE_STRING); 00775 if (value == NULL) 00776 ret = WS_MEMORY_E; 00777 } 00778 00779 if (ret == WS_SUCCESS) { 00780 WSTRNCPY(value, username, valueSz + 1); 00781 if (ssh->userName != NULL) { 00782 WFREE(ssh->userName, heap, DYNTYPE_STRING); 00783 ssh->userName = NULL; 00784 } 00785 ssh->userName = value; 00786 ssh->userNameSz = valueSz; 00787 } 00788 00789 return ret; 00790 } 00791 00792 00793 int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx, 00794 const char* newBanner) 00795 { 00796 word32 newBannerSz = 0; 00797 00798 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_SetBanner()"); 00799 00800 if (ctx == NULL) 00801 return WS_BAD_ARGUMENT; 00802 00803 if (newBanner != NULL) { 00804 WLOG(WS_LOG_INFO, " setting banner to: \"%s\"", newBanner); 00805 newBannerSz = (word32)WSTRLEN(newBanner); 00806 } 00807 00808 ctx->banner = newBanner; 00809 ctx->bannerSz = newBannerSz; 00810 00811 return WS_SUCCESS; 00812 } 00813 00814 00815 int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX* ctx, 00816 const byte* in, word32 inSz, int format) 00817 { 00818 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_UsePrivateKey_buffer()"); 00819 return wolfSSH_ProcessBuffer(ctx, in, inSz, format, BUFTYPE_PRIVKEY); 00820 } 00821 00822 00823 void wolfSSH_GetStats(WOLFSSH* ssh, word32* txCount, word32* rxCount, 00824 word32* seq, word32* peerSeq) 00825 { 00826 word32 rTxCount = 0; 00827 word32 rRxCount = 0; 00828 word32 rSeq = 0; 00829 word32 rPeerSeq = 0; 00830 00831 if (ssh != NULL) { 00832 rTxCount = ssh->txCount; 00833 rRxCount = ssh->rxCount; 00834 rSeq = ssh->seq; 00835 rPeerSeq = ssh->peerSeq; 00836 } 00837 00838 if (txCount != NULL) 00839 *txCount = rTxCount; 00840 if (rxCount != NULL) 00841 *rxCount = rRxCount; 00842 if (seq != NULL) 00843 *seq = rSeq; 00844 if (peerSeq != NULL) 00845 *peerSeq = rPeerSeq; 00846 } 00847 00848 00849 int wolfSSH_KDF(byte hashId, byte keyId, 00850 byte* key, word32 keySz, 00851 const byte* k, word32 kSz, 00852 const byte* h, word32 hSz, 00853 const byte* sessionId, word32 sessionIdSz) 00854 { 00855 WLOG(WS_LOG_DEBUG, "Entering wolfSSH_KDF()"); 00856 return GenerateKey(hashId, keyId, key, keySz, k, kSz, h, hSz, 00857 sessionId, sessionIdSz); 00858 } 00859
Generated on Tue Jul 12 2022 21:46:52 by 1.7.2