ssh_server.c
Go to the documentation of this file.
1 /**
2  * @file ssh_server.c
3  * @brief SSH server
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSH Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SSH_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ssh/ssh.h"
36 #include "ssh/ssh_misc.h"
37 #include "ssh/ssh_server.h"
38 #include "ssh/ssh_server_misc.h"
39 #include "debug.h"
40 
41 //Check SSH stack configuration
42 #if (SSH_SUPPORT == ENABLED && SSH_SERVER_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Initialize settings with default values
47  * @param[out] settings Structure that contains SSH server settings
48  **/
49 
51 {
52  //Default task parameters
53  settings->task = OS_TASK_DEFAULT_PARAMS;
55  settings->task.priority = SSH_SERVER_PRIORITY;
56 
57  //The SSH server is not bound to any interface
58  settings->interface = NULL;
59 
60  //SSH port number
61  settings->port = SSH_PORT;
62  //Idle connection timeout
63  settings->timeout = SSH_SERVER_TIMEOUT;
64 
65  //SSH connections
66  settings->numConnections = 0;
67  settings->connections = NULL;
68 
69  //SSH channels
70  settings->numChannels = 0;
71  settings->channels = NULL;
72 
73  //Pseudo-random number generator
74  settings->prngAlgo = NULL;
75  settings->prngContext = NULL;
76 
77 #if (SSH_PUBLIC_KEY_AUTH_SUPPORT == ENABLED)
78  //Public key authentication callback function
79  settings->publicKeyAuthCallback = NULL;
80 #endif
81 
82 #if (SSH_PUBLIC_KEY_AUTH_SUPPORT == ENABLED && SSH_CERT_SUPPORT == ENABLED)
83  //Certificate authentication callback function
84  settings->certAuthCallback = NULL;
85  //CA public key verification callback function
86  settings->caPublicKeyVerifyCallback = NULL;
87 #endif
88 
89 #if (SSH_PASSWORD_AUTH_SUPPORT == ENABLED)
90  //Password authentication callback function
91  settings->passwordAuthCallback = NULL;
92  //Password change callback function
93  settings->passwordChangeCallback = NULL;
94 #endif
95 
96 #if (SSH_SIGN_CALLBACK_SUPPORT == ENABLED)
97  //Signature generation callback function
98  settings->signGenCallback = NULL;
99  //Signature verification callback function
100  settings->signVerifyCallback = NULL;
101 #endif
102 
103 #if (SSH_ECDH_CALLBACK_SUPPORT == ENABLED)
104  //ECDH key pair generation callback
105  settings->ecdhKeyPairGenCallback = NULL;
106  //ECDH shared secret calculation callback
107  settings->ecdhSharedSecretCalcCallback = NULL;
108 #endif
109 
110 #if (SSH_KEY_LOG_SUPPORT == ENABLED)
111  //Key logging callback (for debugging purpose only)
112  settings->keyLogCallback = NULL;
113 #endif
114 }
115 
116 
117 /**
118  * @brief Initialize SSH server context
119  * @param[in] context Pointer to the SSH server context
120  * @param[in] settings SSH server specific settings
121  * @return Error code
122  **/
123 
125  const SshServerSettings *settings)
126 {
127  error_t error;
128 
129  //Debug message
130  TRACE_INFO("Initializing SSH server...\r\n");
131 
132  //Ensure the parameters are valid
133  if(context == NULL || settings == NULL)
135 
136  //Invalid number of SSH connections?
137  if(settings->numConnections < 1 ||
139  {
141  }
142 
143  //Invalid number of SSH channels?
144  if(settings->numChannels < settings->numConnections)
146 
147  //Clear SSH server context
148  osMemset(context, 0, sizeof(SshServerContext));
149 
150  //Initialize SSH context
151  error = sshInit(&context->sshContext, settings->connections,
152  settings->numConnections, settings->channels, settings->numChannels);
153  //Any error to report?
154  if(error)
155  return error;
156 
157  //Initialize task parameters
158  context->taskParams = settings->task;
159  context->taskId = OS_INVALID_TASK_ID;
160 
161  //Save settings
162  context->interface = settings->interface;
163  context->port = settings->port;
164  context->timeout = settings->timeout;
165 
166  //Start of exception handling block
167  do
168  {
169  //Select server operation mode
170  error = sshSetOperationMode(&context->sshContext,
172  //Any error to report?
173  if(error)
174  break;
175 
176  //Set the pseudo-random number generator to be used
177  error = sshSetPrng(&context->sshContext, settings->prngAlgo,
178  settings->prngContext);
179  //Any error to report?
180  if(error)
181  break;
182 
183 #if (SSH_PUBLIC_KEY_AUTH_SUPPORT == ENABLED)
184  //Valid public key authentication callback function?
185  if(settings->publicKeyAuthCallback != NULL)
186  {
187  //Register callback function
189  settings->publicKeyAuthCallback);
190  //Any error to report?
191  if(error)
192  break;
193  }
194 #endif
195 
196 #if (SSH_PUBLIC_KEY_AUTH_SUPPORT == ENABLED && SSH_CERT_SUPPORT == ENABLED)
197  //Valid certificate authentication callback function?
198  if(settings->certAuthCallback != NULL)
199  {
200  //Register callback function
201  error = sshRegisterCertAuthCallback(&context->sshContext,
202  settings->certAuthCallback);
203  //Any error to report?
204  if(error)
205  break;
206  }
207 
208  //Valid CA public key verification callback function?
209  if(settings->caPublicKeyVerifyCallback != NULL)
210  {
211  //Register callback function
213  settings->caPublicKeyVerifyCallback);
214  //Any error to report?
215  if(error)
216  break;
217  }
218 #endif
219 
220 #if (SSH_PASSWORD_AUTH_SUPPORT == ENABLED)
221  //Valid password authentication callback function?
222  if(settings->passwordAuthCallback != NULL)
223  {
224  //Register callback function
226  settings->passwordAuthCallback);
227  //Any error to report?
228  if(error)
229  break;
230  }
231 
232  //Valid password change callback function?
233  if(settings->passwordChangeCallback != NULL)
234  {
235  //Register callback function
237  settings->passwordChangeCallback);
238  //Any error to report?
239  if(error)
240  break;
241  }
242 #endif
243 
244 #if (SSH_SIGN_CALLBACK_SUPPORT == ENABLED)
245  //Valid signature generation callback function?
246  if(settings->signGenCallback != NULL)
247  {
248  //Register callback function
249  error = sshRegisterSignGenCallback(&context->sshContext,
250  settings->signGenCallback);
251  //Any error to report?
252  if(error)
253  break;
254  }
255 
256  //Valid signature verification callback function?
257  if(settings->signVerifyCallback != NULL)
258  {
259  //Register callback function
260  error = sshRegisterSignVerifyCallback(&context->sshContext,
261  settings->signVerifyCallback);
262  //Any error to report?
263  if(error)
264  break;
265  }
266 #endif
267 
268 #if (SSH_ECDH_CALLBACK_SUPPORT == ENABLED)
269  //Valid ECDH key pair generation callback function?
270  if(settings->ecdhKeyPairGenCallback != NULL)
271  {
272  //Register callback function
274  settings->ecdhKeyPairGenCallback);
275  //Any error to report?
276  if(error)
277  break;
278  }
279 
280  //Valid ECDH shared secret calculation callback function?
281  if(settings->ecdhSharedSecretCalcCallback != NULL)
282  {
283  //Register callback function
285  settings->ecdhSharedSecretCalcCallback);
286  //Any error to report?
287  if(error)
288  break;
289  }
290 #endif
291 
292 #if (SSH_KEY_LOG_SUPPORT == ENABLED)
293  //Valid key logging callback function?
294  if(settings->keyLogCallback != NULL)
295  {
296  //Register callback function
297  error = sshRegisterKeyLogCallback(&context->sshContext,
298  settings->keyLogCallback);
299  //Any error to report?
300  if(error)
301  break;
302  }
303 #endif
304 
305  //End of exception handling block
306  } while(0);
307 
308  //Check status code
309  if(error)
310  {
311  //Clean up side effects
312  sshServerDeinit(context);
313  }
314 
315  //Return status code
316  return error;
317 }
318 
319 
320 /**
321  * @brief Register global request callback function
322  * @param[in] context Pointer to the SSH server context
323  * @param[in] callback Global request callback function
324  * @param[in] param An opaque pointer passed to the callback function
325  * @return Error code
326  **/
327 
329  SshGlobalReqCallback callback, void *param)
330 {
331  //Register global request callback function
332  return sshRegisterGlobalRequestCallback(&context->sshContext, callback,
333  param);
334 }
335 
336 
337 /**
338  * @brief Unregister global request callback function
339  * @param[in] context Pointer to the SSH server context
340  * @param[in] callback Previously registered callback function
341  * @return Error code
342  **/
343 
345  SshGlobalReqCallback callback)
346 {
347  //Unregister global request callback function
348  return sshUnregisterGlobalRequestCallback(&context->sshContext, callback);
349 }
350 
351 
352 /**
353  * @brief Register channel request callback function
354  * @param[in] context Pointer to the SSH server context
355  * @param[in] callback Channel request callback function
356  * @param[in] param An opaque pointer passed to the callback function
357  * @return Error code
358  **/
359 
361  SshChannelReqCallback callback, void *param)
362 {
363  //Register channel request callback function
364  return sshRegisterChannelRequestCallback(&context->sshContext, callback,
365  param);
366 }
367 
368 
369 /**
370  * @brief Unregister channel request callback function
371  * @param[in] context Pointer to the SSH server context
372  * @param[in] callback Previously registered callback function
373  * @return Error code
374  **/
375 
377  SshChannelReqCallback callback)
378 {
379  //Unregister channel request callback function
380  return sshUnregisterChannelRequestCallback(&context->sshContext, callback);
381 }
382 
383 
384 /**
385  * @brief Register channel open callback function
386  * @param[in] context Pointer to the SSH server context
387  * @param[in] callback Channel open callback function
388  * @param[in] param An opaque pointer passed to the callback function
389  * @return Error code
390  **/
391 
393  SshChannelOpenCallback callback, void *param)
394 {
395  //Register channel open callback function
396  return sshRegisterChannelOpenCallback(&context->sshContext, callback,
397  param);
398 }
399 
400 
401 /**
402  * @brief Unregister channel open callback function
403  * @param[in] context Pointer to the SSH server context
404  * @param[in] callback Previously registered callback function
405  * @return Error code
406  **/
407 
409  SshChannelOpenCallback callback)
410 {
411  //Unregister channel open callback function
412  return sshUnregisterChannelOpenCallback(&context->sshContext, callback);
413 }
414 
415 
416 /**
417  * @brief Register connection open callback function
418  * @param[in] context Pointer to the SSH server context
419  * @param[in] callback Connection open callback function
420  * @param[in] param An opaque pointer passed to the callback function
421  * @return Error code
422  **/
423 
425  SshConnectionOpenCallback callback, void *param)
426 {
427  //Register connection open callback function
428  return sshRegisterConnectionOpenCallback(&context->sshContext, callback,
429  param);
430 }
431 
432 
433 /**
434  * @brief Unregister connection open callback function
435  * @param[in] context Pointer to the SSH server context
436  * @param[in] callback Previously registered callback function
437  * @return Error code
438  **/
439 
441  SshConnectionOpenCallback callback)
442 {
443  //Unregister connection open callback function
444  return sshUnregisterConnectionOpenCallback(&context->sshContext, callback);
445 }
446 
447 
448 /**
449  * @brief Register connection close callback function
450  * @param[in] context Pointer to the SSH server context
451  * @param[in] callback Connection close callback function
452  * @param[in] param An opaque pointer passed to the callback function
453  * @return Error code
454  **/
455 
457  SshConnectionCloseCallback callback, void *param)
458 {
459  //Register connection close callback function
460  return sshRegisterConnectionCloseCallback(&context->sshContext, callback,
461  param);
462 }
463 
464 
465 /**
466  * @brief Unregister connection close callback function
467  * @param[in] context Pointer to the SSH server context
468  * @param[in] callback Previously registered callback function
469  * @return Error code
470  **/
471 
474 {
475  //Unregister connection close callback function
476  return sshUnregisterConnectionCloseCallback(&context->sshContext, callback);
477 }
478 
479 
480 /**
481  * @brief Load transient RSA key (for RSA key exchange)
482  * @param[in] context Pointer to the SSH server context
483  * @param[in] index Zero-based index identifying a slot
484  * @param[in] publicKey RSA public key (PEM, SSH2 or OpenSSH format). This
485  * parameter is taken as reference
486  * @param[in] publicKeyLen Length of the RSA public key
487  * @param[in] privateKey RSA private key (PEM or OpenSSH format). This
488  * parameter is taken as reference
489  * @param[in] password NULL-terminated string containing the password. This
490  * parameter is required if the private key is encrypted
491  * @param[in] privateKeyLen Length of the RSA private key
492  * @return Error code
493  **/
494 
496  const char_t *publicKey, size_t publicKeyLen, const char_t *privateKey,
497  size_t privateKeyLen, const char_t *password)
498 {
499  //Load the specified transient RSA key
500  return sshLoadRsaKey(&context->sshContext, index, publicKey,
501  publicKeyLen, privateKey, privateKeyLen, password);
502 }
503 
504 
505 /**
506  * @brief Unload transient RSA key (for RSA key exchange)
507  * @param[in] context Pointer to the SSH server context
508  * @param[in] index Zero-based index identifying a slot
509  * @return Error code
510  **/
511 
513 {
514  //Unload the specified transient RSA key
515  return sshUnloadRsaKey(&context->sshContext, index);
516 }
517 
518 
519 /**
520  * @brief Load Diffie-Hellman group
521  * @param[in] context Pointer to the SSH server context
522  * @param[in] index Zero-based index identifying a slot
523  * @param[in] dhParams Diffie-Hellman parameters (PEM format). This parameter
524  * is taken as reference
525  * @param[in] dhParamsLen Length of the Diffie-Hellman parameters
526  * @return Error code
527  **/
528 
530  const char_t *dhParams, size_t dhParamsLen)
531 {
532  //Load the specified Diffie-Hellman group
533  return sshLoadDhGexGroup(&context->sshContext, index, dhParams,
534  dhParamsLen);
535 }
536 
537 
538 /**
539  * @brief Unload Diffie-Hellman group
540  * @param[in] context Pointer to the SSH server context
541  * @param[in] index Zero-based index identifying a slot
542  * @return Error code
543  **/
544 
546 {
547  //Unload the specified Diffie-Hellman group
548  return sshUnloadDhGexGroup(&context->sshContext, index);
549 }
550 
551 
552 /**
553  * @brief Load server's host key
554  * @param[in] context Pointer to the SSH server context
555  * @param[in] index Zero-based index identifying a slot
556  * @param[in] publicKey Public key (PEM, SSH2 or OpenSSH format). This parameter
557  * is taken as reference
558  * @param[in] publicKeyLen Length of the public key
559  * @param[in] privateKey Private key (PEM or OpenSSH format). This parameter is
560  * taken as reference
561  * @param[in] privateKeyLen Length of the private key
562  * @param[in] password NULL-terminated string containing the password. This
563  * parameter is required if the private key is encrypted
564  * @return Error code
565  **/
566 
568  const char_t *publicKey, size_t publicKeyLen, const char_t *privateKey,
569  size_t privateKeyLen, const char_t *password)
570 {
571  //Load the specified key pair
572  return sshLoadHostKey(&context->sshContext, index, publicKey, publicKeyLen,
573  privateKey, privateKeyLen, password);
574 }
575 
576 
577 /**
578  * @brief Unload server's host key
579  * @param[in] index Zero-based index identifying a slot
580  * @param[in] context Pointer to the SSH server context
581  * @return Error code
582  **/
583 
585 {
586  //Unload the specified key pair
587  return sshUnloadHostKey(&context->sshContext, index);
588 }
589 
590 
591 /**
592  * @brief Load server's certificate
593  * @param[in] context Pointer to the SSH server context
594  * @param[in] index Zero-based index identifying a slot
595  * @param[in] cert Certificate (OpenSSH format). This parameter is taken
596  * as reference
597  * @param[in] certLen Length of the certificate
598  * @param[in] privateKey Private key (PEM or OpenSSH format). This parameter
599  * is taken as reference
600  * @param[in] privateKeyLen Length of the private key
601  * @param[in] password NULL-terminated string containing the password. This
602  * parameter is required if the private key is encrypted
603  * @return Error code
604  **/
605 
607  const char_t *cert, size_t certLen, const char_t *privateKey,
608  size_t privateKeyLen, const char_t *password)
609 {
610 #if (SSH_CERT_SUPPORT == ENABLED)
611  //Load the specified certificate
612  return sshLoadCertificate(&context->sshContext, index, cert, certLen,
613  privateKey, privateKeyLen, password);
614 #else
615  //Not implemented
616  return ERROR_NOT_IMPLEMENTED;
617 #endif
618 }
619 
620 
621 /**
622  * @brief Unload server's certificate
623  * @param[in] index Zero-based index identifying a slot
624  * @param[in] context Pointer to the SSH server context
625  * @return Error code
626  **/
627 
629 {
630 #if (SSH_CERT_SUPPORT == ENABLED)
631  //Unload the specified certificate
632  return sshUnloadCertificate(&context->sshContext, index);
633 #else
634  //Not implemented
635  return ERROR_NOT_IMPLEMENTED;
636 #endif
637 }
638 
639 
640 /**
641  * @brief Start SSH server
642  * @param[in] context Pointer to the SSH server context
643  * @return Error code
644  **/
645 
647 {
648  error_t error;
649 
650  //Make sure the SSH server context is valid
651  if(context == NULL)
653 
654  //Debug message
655  TRACE_INFO("Starting SSH server...\r\n");
656 
657  //Make sure the SSH server is not already running
658  if(context->running)
659  return ERROR_ALREADY_RUNNING;
660 
661  //Start of exception handling block
662  do
663  {
664  //Open a TCP socket
666 
667  //Failed to open socket?
668  if(context->socket == NULL)
669  {
670  //Report an error
671  error = ERROR_OPEN_FAILED;
672  //Exit immediately
673  break;
674  }
675 
676  //Force the socket to operate in non-blocking mode
677  error = socketSetTimeout(context->socket, 0);
678  //Any error to report?
679  if(error)
680  break;
681 
682  //Associate the socket with the relevant interface
683  error = socketBindToInterface(context->socket, context->interface);
684  //Any error to report?
685  if(error)
686  break;
687 
688  //The SSH server listens for connection requests on port 22
689  error = socketBind(context->socket, &IP_ADDR_ANY, context->port);
690  //Any error to report?
691  if(error)
692  break;
693 
694  //Place socket in listening state
695  error = socketListen(context->socket, 0);
696  //Any error to report?
697  if(error)
698  break;
699 
700  //Start the SSH server
701  context->stop = FALSE;
702  context->running = TRUE;
703 
704  //Create a task
705  context->taskId = osCreateTask("SSH Server", (OsTaskCode) sshServerTask,
706  context, &context->taskParams);
707 
708  //Failed to create task?
709  if(context->taskId == OS_INVALID_TASK_ID)
710  {
711  //Report an error
712  error = ERROR_OUT_OF_RESOURCES;
713  break;
714  }
715 
716  //End of exception handling block
717  } while(0);
718 
719  //Any error to report?
720  if(error)
721  {
722  //Clean up side effects
723  context->running = FALSE;
724 
725  //Close listening socket
726  socketClose(context->socket);
727  context->socket = NULL;
728  }
729 
730  //Return status code
731  return error;
732 }
733 
734 
735 /**
736  * @brief Stop SSH server
737  * @param[in] context Pointer to the SSH server context
738  * @return Error code
739  **/
740 
742 {
743  uint_t i;
744 
745  //Make sure the SSH server context is valid
746  if(context == NULL)
748 
749  //Debug message
750  TRACE_INFO("Stopping SSH server...\r\n");
751 
752  //Check whether the SSH server is running
753  if(context->running)
754  {
755  //Stop the SSH server
756  context->stop = TRUE;
757  //Send a signal to the task to abort any blocking operation
758  sshNotifyEvent(&context->sshContext);
759 
760  //Wait for the task to terminate
761  while(context->running)
762  {
763  osDelayTask(1);
764  }
765 
766  //Loop through SSH connections
767  for(i = 0; i < context->sshContext.numConnections; i++)
768  {
769  //Active connection?
770  if(context->sshContext.connections[i].state != SSH_CONN_STATE_CLOSED)
771  {
772  //Close the SSH connection
773  sshCloseConnection(&context->sshContext.connections[i]);
774  }
775  }
776 
777  //Close listening socket
778  socketClose(context->socket);
779  context->socket = NULL;
780  }
781 
782  //Successful processing
783  return NO_ERROR;
784 }
785 
786 
787 /**
788  * @brief SSH server task
789  * @param[in] context Pointer to the SSH server context
790  **/
791 
793 {
794  error_t error;
795  uint_t i;
796  SshContext *sshContext;
797  SshConnection *connection;
798 
799  //Point to the SSH context
800  sshContext = &context->sshContext;
801 
802 #if (NET_RTOS_SUPPORT == ENABLED)
803  //Task prologue
804  osEnterTask();
805 
806  //Process events
807  while(1)
808  {
809 #endif
810  //Clear event descriptor set
811  osMemset(sshContext->eventDesc, 0, sizeof(sshContext->eventDesc));
812 
813  //Specify the events the application is interested in
814  for(i = 0; i < sshContext->numConnections; i++)
815  {
816  //Point to the structure describing the current connection
817  connection = &sshContext->connections[i];
818 
819  //Loop through active connections only
820  if(connection->state != SSH_CONN_STATE_CLOSED)
821  {
822  //Register the events related to the current SSH connection
823  sshRegisterConnectionEvents(sshContext, connection,
824  &sshContext->eventDesc[i]);
825  }
826  }
827 
828  //The SSH server listens for connection requests on port 22
829  sshContext->eventDesc[i].socket = context->socket;
830  sshContext->eventDesc[i].eventMask = SOCKET_EVENT_ACCEPT;
831 
832  //Wait for one of the set of sockets to become ready to perform I/O
833  error = socketPoll(sshContext->eventDesc, sshContext->numConnections + 1,
834  &sshContext->event, SSH_SERVER_TICK_INTERVAL);
835 
836  //Check status code
837  if(error == NO_ERROR || error == ERROR_TIMEOUT ||
838  error == ERROR_WAIT_CANCELED)
839  {
840  //Stop request?
841  if(context->stop)
842  {
843  //Stop SSH server operation
844  context->running = FALSE;
845  //Task epilogue
846  osExitTask();
847  //Kill ourselves
849  }
850 
851  //Event-driven processing
852  for(i = 0; i < sshContext->numConnections; i++)
853  {
854  //Point to the structure describing the current connection
855  connection = &sshContext->connections[i];
856 
857  //Loop through active connections only
858  if(connection->state != SSH_CONN_STATE_CLOSED)
859  {
860  //Check whether the socket is ready to perform I/O
861  if(sshContext->eventDesc[i].eventFlags != 0)
862  {
863  //Connection event handler
864  error = sshProcessConnectionEvents(sshContext, connection);
865 
866  //Any communication error?
867  if(error != NO_ERROR && error != ERROR_TIMEOUT)
868  {
869  //Close the SSH connection
870  sshCloseConnection(connection);
871  }
872  }
873  }
874  }
875 
876  //Any connection request received on port 22?
877  if(sshContext->eventDesc[i].eventFlags != 0)
878  {
879  //Accept connection request
880  sshServerAcceptConnection(context);
881  }
882  }
883 
884  //Handle periodic operations
885  sshServerTick(context);
886 
887 #if (NET_RTOS_SUPPORT == ENABLED)
888  }
889 #endif
890 }
891 
892 
893 /**
894  * @brief Release SSH server context
895  * @param[in] context Pointer to the SSH server context
896  **/
897 
899 {
900  //Make sure the SSH server context is valid
901  if(context != NULL)
902  {
903  //Close listening socket
904  socketClose(context->socket);
905 
906  //Release SSH context
907  sshDeinit(&context->sshContext);
908 
909  //Clear SSH server context
910  osMemset(context, 0, sizeof(SshServerContext));
911  }
912 }
913 
914 #endif
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
error_t
Error codes.
Definition: error.h:43
@ ERROR_WAIT_CANCELED
Definition: error.h:73
@ ERROR_ALREADY_RUNNING
Definition: error.h:292
@ ERROR_TIMEOUT
Definition: error.h:95
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_OPEN_FAILED
Definition: error.h:75
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
const IpAddr IP_ADDR_ANY
Definition: ip.c:51
#define socketBindToInterface
Definition: net_legacy.h:193
#define osMemset(p, value, length)
Definition: os_port.h:135
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
const OsTaskParameters OS_TASK_DEFAULT_PARAMS
void osDelayTask(systime_t delay)
Delay routine.
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
void osDeleteTask(OsTaskId taskId)
Delete a task.
void(* OsTaskCode)(void *arg)
Task routine.
#define osEnterTask()
#define OS_SELF_TASK_ID
#define OS_INVALID_TASK_ID
#define osExitTask()
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:778
error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent, systime_t timeout)
Wait for one of a set of sockets to become ready to perform I/O.
Definition: socket.c:1592
error_t socketListen(Socket *socket, uint_t backlog)
Place a socket in the listening state.
Definition: socket.c:875
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:125
error_t socketSetTimeout(Socket *socket, systime_t timeout)
Set timeout value for blocking operations.
Definition: socket.c:148
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:1517
@ SOCKET_IP_PROTO_TCP
Definition: socket.h:100
@ SOCKET_TYPE_STREAM
Definition: socket.h:85
@ SOCKET_EVENT_ACCEPT
Definition: socket.h:162
error_t sshUnregisterChannelRequestCallback(SshContext *context, SshChannelReqCallback callback)
Unregister channel request callback function.
Definition: ssh.c:752
error_t sshUnregisterChannelOpenCallback(SshContext *context, SshChannelOpenCallback callback)
Unregister channel open callback function.
Definition: ssh.c:839
error_t sshUnregisterGlobalRequestCallback(SshContext *context, SshGlobalReqCallback callback)
Unregister global request callback function.
Definition: ssh.c:665
error_t sshSetOperationMode(SshContext *context, SshOperationMode mode)
Set operation mode (client or server)
Definition: ssh.c:167
error_t sshLoadHostKey(SshContext *context, uint_t index, const char_t *publicKey, size_t publicKeyLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load entity's host key.
Definition: ssh.c:1353
error_t sshUnloadDhGexGroup(SshContext *context, uint_t index)
Unload Diffie-Hellman group.
Definition: ssh.c:1311
error_t sshLoadCertificate(SshContext *context, uint_t index, const char_t *cert, size_t certLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load entity's certificate.
Definition: ssh.c:1682
error_t sshRegisterSignVerifyCallback(SshContext *context, SshSignVerifyCallback callback)
Register signature verification callback function.
Definition: ssh.c:524
error_t sshRegisterPasswordChangeCallback(SshContext *context, SshPasswordChangeCallback callback)
Register password change callback function.
Definition: ssh.c:462
error_t sshRegisterGlobalRequestCallback(SshContext *context, SshGlobalReqCallback callback, void *param)
Register global request callback function.
Definition: ssh.c:618
error_t sshLoadDhGexGroup(SshContext *context, uint_t index, const char_t *dhParams, size_t dhParamsLen)
Load Diffie-Hellman group.
Definition: ssh.c:1234
error_t sshRegisterChannelRequestCallback(SshContext *context, SshChannelReqCallback callback, void *param)
Register channel request callback function.
Definition: ssh.c:705
error_t sshRegisterEcdhKeyPairGenCallback(SshContext *context, SshEcdhKeyPairGenCallback callback)
Register ECDH key pair generation callback function.
Definition: ssh.c:555
error_t sshRegisterKeyLogCallback(SshContext *context, SshKeyLogCallback callback)
Register key logging callback function (for debugging purpose only)
Definition: ssh.c:1052
error_t sshRegisterPasswordAuthCallback(SshContext *context, SshPasswordAuthCallback callback)
Register password authentication callback function.
Definition: ssh.c:431
error_t sshRegisterConnectionCloseCallback(SshContext *context, SshConnectionCloseCallback callback, void *param)
Register connection close callback function.
Definition: ssh.c:966
error_t sshUnloadCertificate(SshContext *context, uint_t index)
Unload entity's certificate.
Definition: ssh.c:1874
error_t sshRegisterCertAuthCallback(SshContext *context, SshCertAuthCallback callback)
Register certificate authentication callback function.
Definition: ssh.c:400
error_t sshRegisterChannelOpenCallback(SshContext *context, SshChannelOpenCallback callback, void *param)
Register channel open callback function.
Definition: ssh.c:792
error_t sshRegisterEcdhSharedSecretCalcCallback(SshContext *context, SshEcdhSharedSecretCalcCallback callback)
Register ECDH shared secret calculation callback function.
Definition: ssh.c:586
error_t sshSetPrng(SshContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Set the pseudo-random number generator to be used.
Definition: ssh.c:193
error_t sshInit(SshContext *context, SshConnection *connections, uint_t numConnections, SshChannel *channels, uint_t numChannels)
SSH context initialization.
Definition: ssh.c:58
error_t sshUnloadRsaKey(SshContext *context, uint_t index)
Unload transient RSA key (for RSA key exchange)
Definition: ssh.c:1197
error_t sshRegisterConnectionOpenCallback(SshContext *context, SshConnectionOpenCallback callback, void *param)
Register connection open callback function.
Definition: ssh.c:879
error_t sshUnregisterConnectionCloseCallback(SshContext *context, SshConnectionCloseCallback callback)
Unregister connection close callback function.
Definition: ssh.c:1013
error_t sshUnloadHostKey(SshContext *context, uint_t index)
Unload entity's host key.
Definition: ssh.c:1619
error_t sshUnregisterConnectionOpenCallback(SshContext *context, SshConnectionOpenCallback callback)
Unregister connection open callback function.
Definition: ssh.c:926
error_t sshRegisterPublicKeyAuthCallback(SshContext *context, SshPublicKeyAuthCallback callback)
Register public key authentication callback function.
Definition: ssh.c:369
error_t sshLoadRsaKey(SshContext *context, uint_t index, const char_t *publicKey, size_t publicKeyLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load transient RSA key (for RSA key exchange)
Definition: ssh.c:1087
error_t sshRegisterCaPublicKeyVerifyCallback(SshContext *context, SshCaPublicKeyVerifyCallback callback)
Register CA public key verification callback function.
Definition: ssh.c:338
void sshDeinit(SshContext *context)
Release SSH context.
Definition: ssh.c:2556
error_t sshRegisterSignGenCallback(SshContext *context, SshSignGenCallback callback)
Register signature generation callback function.
Definition: ssh.c:493
Secure Shell (SSH)
error_t(* SshChannelOpenCallback)(SshConnection *connection, const SshString *type, uint32_t senderChannel, uint32_t initialWindowSize, uint32_t maxPacketSize, const uint8_t *data, size_t length, void *param)
Channel open callback function.
Definition: ssh.h:1291
error_t(* SshChannelReqCallback)(SshChannel *channel, const SshString *type, const uint8_t *data, size_t length, void *param)
Channel request callback function.
Definition: ssh.h:1283
error_t(* SshConnectionOpenCallback)(SshConnection *connection, void *param)
Connection open callback function.
Definition: ssh.h:1300
void(* SshConnectionCloseCallback)(SshConnection *connection, void *param)
Connection close callback function.
Definition: ssh.h:1308
@ SSH_CONN_STATE_CLOSED
Definition: ssh.h:1042
error_t(* SshGlobalReqCallback)(SshConnection *connection, const SshString *name, const uint8_t *data, size_t length, void *param)
Global request callback function.
Definition: ssh.h:1275
@ SSH_OPERATION_MODE_SERVER
Definition: ssh.h:902
#define SSH_PORT
Definition: ssh.h:865
#define SshConnection
Definition: ssh.h:883
#define SSH_MAX_CONNECTIONS
Definition: ssh.h:185
#define SshContext
Definition: ssh.h:879
error_t sshProcessConnectionEvents(SshContext *context, SshConnection *connection)
Connection event handler.
Definition: ssh_misc.c:372
void sshRegisterConnectionEvents(SshContext *context, SshConnection *connection, SocketEventDesc *eventDesc)
Register connection events.
Definition: ssh_misc.c:280
void sshCloseConnection(SshConnection *connection)
Close SSH connection.
Definition: ssh_misc.c:172
void sshNotifyEvent(SshContext *context)
Notify the SSH context that event is occurring.
Definition: ssh_misc.c:709
SSH helper functions.
error_t sshServerRegisterChannelRequestCallback(SshServerContext *context, SshChannelReqCallback callback, void *param)
Register channel request callback function.
Definition: ssh_server.c:360
error_t sshServerStart(SshServerContext *context)
Start SSH server.
Definition: ssh_server.c:646
error_t sshServerUnregisterGlobalRequestCallback(SshServerContext *context, SshGlobalReqCallback callback)
Unregister global request callback function.
Definition: ssh_server.c:344
error_t sshServerLoadRsaKey(SshServerContext *context, uint_t index, const char_t *publicKey, size_t publicKeyLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load transient RSA key (for RSA key exchange)
Definition: ssh_server.c:495
error_t sshServerUnloadRsaKey(SshServerContext *context, uint_t index)
Unload transient RSA key (for RSA key exchange)
Definition: ssh_server.c:512
error_t sshServerUnregisterChannelRequestCallback(SshServerContext *context, SshChannelReqCallback callback)
Unregister channel request callback function.
Definition: ssh_server.c:376
error_t sshServerLoadHostKey(SshServerContext *context, uint_t index, const char_t *publicKey, size_t publicKeyLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load server's host key.
Definition: ssh_server.c:567
error_t sshServerUnloadHostKey(SshServerContext *context, uint_t index)
Unload server's host key.
Definition: ssh_server.c:584
error_t sshServerRegisterGlobalRequestCallback(SshServerContext *context, SshGlobalReqCallback callback, void *param)
Register global request callback function.
Definition: ssh_server.c:328
error_t sshServerRegisterConnectionOpenCallback(SshServerContext *context, SshConnectionOpenCallback callback, void *param)
Register connection open callback function.
Definition: ssh_server.c:424
error_t sshServerUnregisterConnectionOpenCallback(SshServerContext *context, SshConnectionOpenCallback callback)
Unregister connection open callback function.
Definition: ssh_server.c:440
error_t sshServerUnloadCertificate(SshServerContext *context, uint_t index)
Unload server's certificate.
Definition: ssh_server.c:628
error_t sshServerRegisterChannelOpenCallback(SshServerContext *context, SshChannelOpenCallback callback, void *param)
Register channel open callback function.
Definition: ssh_server.c:392
error_t sshServerInit(SshServerContext *context, const SshServerSettings *settings)
Initialize SSH server context.
Definition: ssh_server.c:124
error_t sshServerUnregisterChannelOpenCallback(SshServerContext *context, SshChannelOpenCallback callback)
Unregister channel open callback function.
Definition: ssh_server.c:408
error_t sshServerStop(SshServerContext *context)
Stop SSH server.
Definition: ssh_server.c:741
void sshServerDeinit(SshServerContext *context)
Release SSH server context.
Definition: ssh_server.c:898
void sshServerTask(SshServerContext *context)
SSH server task.
Definition: ssh_server.c:792
error_t sshServerLoadDhGexGroup(SshServerContext *context, uint_t index, const char_t *dhParams, size_t dhParamsLen)
Load Diffie-Hellman group.
Definition: ssh_server.c:529
error_t sshServerUnloadDhGexGroup(SshServerContext *context, uint_t index)
Unload Diffie-Hellman group.
Definition: ssh_server.c:545
void sshServerGetDefaultSettings(SshServerSettings *settings)
Initialize settings with default values.
Definition: ssh_server.c:50
error_t sshServerLoadCertificate(SshServerContext *context, uint_t index, const char_t *cert, size_t certLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load server's certificate.
Definition: ssh_server.c:606
error_t sshServerUnregisterConnectionCloseCallback(SshServerContext *context, SshConnectionCloseCallback callback)
Unregister connection close callback function.
Definition: ssh_server.c:472
error_t sshServerRegisterConnectionCloseCallback(SshServerContext *context, SshConnectionCloseCallback callback, void *param)
Register connection close callback function.
Definition: ssh_server.c:456
SSH server.
#define SSH_SERVER_TICK_INTERVAL
Definition: ssh_server.h:58
#define SSH_SERVER_PRIORITY
Definition: ssh_server.h:46
#define SSH_SERVER_TIMEOUT
Definition: ssh_server.h:51
#define SSH_SERVER_STACK_SIZE
Definition: ssh_server.h:39
void sshServerTick(SshServerContext *context)
Handle periodic operations.
void sshServerAcceptConnection(SshServerContext *context)
Accept connection request.
Helper functions for SSH server.
SSH server context.
Definition: ssh_server.h:115
bool_t stop
Stop request.
Definition: ssh_server.h:117
OsTaskId taskId
Task identifier.
Definition: ssh_server.h:119
bool_t running
Operational state of the SSH server.
Definition: ssh_server.h:116
uint16_t port
SSH port number.
Definition: ssh_server.h:122
OsTaskParameters taskParams
Task parameters.
Definition: ssh_server.h:118
SshContext sshContext
SSH context.
Definition: ssh_server.h:124
systime_t timeout
Idle connection timeout.
Definition: ssh_server.h:123
Socket * socket
Listening socket.
Definition: ssh_server.h:121
NetInterface * interface
Underlying network interface.
Definition: ssh_server.h:120
SSH server settings.
Definition: ssh_server.h:74
SshEcdhSharedSecretCalcCallback ecdhSharedSecretCalcCallback
ECDH shared secret calculation callback.
Definition: ssh_server.h:102
OsTaskParameters task
Task parameters.
Definition: ssh_server.h:75
SshPasswordChangeCallback passwordChangeCallback
Password change callback.
Definition: ssh_server.h:94
SshPublicKeyAuthCallback publicKeyAuthCallback
Public key authentication callback.
Definition: ssh_server.h:86
SshCaPublicKeyVerifyCallback caPublicKeyVerifyCallback
CA public key verification callback.
Definition: ssh_server.h:90
SshConnection * connections
SSH connections.
Definition: ssh_server.h:80
uint_t numConnections
Maximum number of SSH connections.
Definition: ssh_server.h:79
const PrngAlgo * prngAlgo
Pseudo-random number generator to be used.
Definition: ssh_server.h:83
SshCertAuthCallback certAuthCallback
Certificate authentication callback.
Definition: ssh_server.h:89
SshEcdhKeyPairGenCallback ecdhKeyPairGenCallback
ECDH key pair generation callback.
Definition: ssh_server.h:101
uint16_t port
SSH port number.
Definition: ssh_server.h:77
SshPasswordAuthCallback passwordAuthCallback
Password authentication callback.
Definition: ssh_server.h:93
uint_t numChannels
Maximum number of SSH channels.
Definition: ssh_server.h:81
systime_t timeout
Idle connection timeout.
Definition: ssh_server.h:78
SshChannel * channels
SSH channels.
Definition: ssh_server.h:82
SshKeyLogCallback keyLogCallback
Key logging callback (for debugging purpose only)
Definition: ssh_server.h:105
SshSignGenCallback signGenCallback
Signature generation callback.
Definition: ssh_server.h:97
NetInterface * interface
Underlying network interface.
Definition: ssh_server.h:76
SshSignVerifyCallback signVerifyCallback
Signature verification callback.
Definition: ssh_server.h:98
void * prngContext
Pseudo-random number generator context.
Definition: ssh_server.h:84