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.4
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 #if (NET_RTOS_SUPPORT == ENABLED)
756  //Stop the SSH server
757  context->stop = TRUE;
758  //Send a signal to the task to abort any blocking operation
759  sshNotifyEvent(&context->sshContext);
760 
761  //Wait for the task to terminate
762  while(context->running)
763  {
764  osDelayTask(1);
765  }
766 #endif
767 
768  //Loop through SSH connections
769  for(i = 0; i < context->sshContext.numConnections; i++)
770  {
771  //Active connection?
772  if(context->sshContext.connections[i].state != SSH_CONN_STATE_CLOSED)
773  {
774  //Close the SSH connection
775  sshCloseConnection(&context->sshContext.connections[i]);
776  }
777  }
778 
779  //Close listening socket
780  socketClose(context->socket);
781  context->socket = NULL;
782  }
783 
784  //Successful processing
785  return NO_ERROR;
786 }
787 
788 
789 /**
790  * @brief SSH server task
791  * @param[in] context Pointer to the SSH server context
792  **/
793 
795 {
796  error_t error;
797  uint_t i;
798  SshContext *sshContext;
799  SshConnection *connection;
800 
801  //Point to the SSH context
802  sshContext = &context->sshContext;
803 
804 #if (NET_RTOS_SUPPORT == ENABLED)
805  //Task prologue
806  osEnterTask();
807 
808  //Process events
809  while(1)
810  {
811 #endif
812  //Clear event descriptor set
813  osMemset(sshContext->eventDesc, 0, sizeof(sshContext->eventDesc));
814 
815  //Specify the events the application is interested in
816  for(i = 0; i < sshContext->numConnections; i++)
817  {
818  //Point to the structure describing the current connection
819  connection = &sshContext->connections[i];
820 
821  //Loop through active connections only
822  if(connection->state != SSH_CONN_STATE_CLOSED)
823  {
824  //Register the events related to the current SSH connection
825  sshRegisterConnectionEvents(sshContext, connection,
826  &sshContext->eventDesc[i]);
827  }
828  }
829 
830  //The SSH server listens for connection requests on port 22
831  sshContext->eventDesc[i].socket = context->socket;
832  sshContext->eventDesc[i].eventMask = SOCKET_EVENT_ACCEPT;
833 
834  //Wait for one of the set of sockets to become ready to perform I/O
835  error = socketPoll(sshContext->eventDesc, sshContext->numConnections + 1,
836  &sshContext->event, SSH_SERVER_TICK_INTERVAL);
837 
838  //Check status code
839  if(error == NO_ERROR || error == ERROR_TIMEOUT ||
840  error == ERROR_WAIT_CANCELED)
841  {
842  //Stop request?
843  if(context->stop)
844  {
845  //Stop SSH server operation
846  context->running = FALSE;
847  //Task epilogue
848  osExitTask();
849  //Kill ourselves
851  }
852 
853  //Event-driven processing
854  for(i = 0; i < sshContext->numConnections; i++)
855  {
856  //Point to the structure describing the current connection
857  connection = &sshContext->connections[i];
858 
859  //Loop through active connections only
860  if(connection->state != SSH_CONN_STATE_CLOSED)
861  {
862  //Check whether the socket is ready to perform I/O
863  if(sshContext->eventDesc[i].eventFlags != 0)
864  {
865  //Connection event handler
866  error = sshProcessConnectionEvents(sshContext, connection);
867 
868  //Any communication error?
869  if(error != NO_ERROR && error != ERROR_TIMEOUT)
870  {
871  //Close the SSH connection
872  sshCloseConnection(connection);
873  }
874  }
875  }
876  }
877 
878  //Any connection request received on port 22?
879  if(sshContext->eventDesc[i].eventFlags != 0)
880  {
881  //Accept connection request
882  sshServerAcceptConnection(context);
883  }
884  }
885 
886  //Handle periodic operations
887  sshServerTick(context);
888 
889 #if (NET_RTOS_SUPPORT == ENABLED)
890  }
891 #endif
892 }
893 
894 
895 /**
896  * @brief Release SSH server context
897  * @param[in] context Pointer to the SSH server context
898  **/
899 
901 {
902  //Make sure the SSH server context is valid
903  if(context != NULL)
904  {
905  //Close listening socket
906  socketClose(context->socket);
907 
908  //Release SSH context
909  sshDeinit(&context->sshContext);
910 
911  //Clear SSH server context
912  osMemset(context, 0, sizeof(SshServerContext));
913  }
914 }
915 
916 #endif
NetInterface * interface
Underlying network interface.
Definition: ssh_server.h:76
error_t(* SshChannelReqCallback)(SshChannel *channel, const SshString *type, const uint8_t *data, size_t length, void *param)
Channel request callback function.
Definition: ssh.h:1274
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:1316
#define SSH_SERVER_TICK_INTERVAL
Definition: ssh_server.h:58
error_t sshUnregisterConnectionOpenCallback(SshContext *context, SshConnectionOpenCallback callback)
Unregister connection open callback function.
Definition: ssh.c:926
#define osExitTask()
void(* SshConnectionCloseCallback)(SshConnection *connection, void *param)
Connection close callback function.
Definition: ssh.h:1299
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
SSH server settings.
Definition: ssh_server.h:74
error_t sshUnloadRsaKey(SshContext *context, uint_t index)
Unload transient RSA key (for RSA key exchange)
Definition: ssh.c:1197
bool_t stop
Stop request.
Definition: ssh_server.h:117
SshEcdhSharedSecretCalcCallback ecdhSharedSecretCalcCallback
ECDH shared secret calculation callback.
Definition: ssh_server.h:102
SshPublicKeyAuthCallback publicKeyAuthCallback
Public key authentication callback.
Definition: ssh_server.h:86
#define TRUE
Definition: os_port.h:50
error_t sshRegisterConnectionCloseCallback(SshContext *context, SshConnectionCloseCallback callback, void *param)
Register connection close callback function.
Definition: ssh.c:966
#define OS_INVALID_TASK_ID
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:2062
error_t sshRegisterChannelRequestCallback(SshContext *context, SshChannelReqCallback callback, void *param)
Register channel request callback function.
Definition: ssh.c:705
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_OUT_OF_RESOURCES
Definition: error.h:64
SshEcdhKeyPairGenCallback ecdhKeyPairGenCallback
ECDH key pair generation callback.
Definition: ssh_server.h:101
error_t sshServerStart(SshServerContext *context)
Start SSH server.
Definition: ssh_server.c:646
error_t sshServerRegisterChannelRequestCallback(SshServerContext *context, SshChannelReqCallback callback, void *param)
Register channel request callback function.
Definition: ssh_server.c:360
#define SSH_PORT
Definition: ssh.h:856
error_t sshUnloadDhGexGroup(SshContext *context, uint_t index)
Unload Diffie-Hellman group.
Definition: ssh.c:1311
error_t sshServerUnregisterChannelRequestCallback(SshServerContext *context, SshChannelReqCallback callback)
Unregister channel request callback function.
Definition: ssh_server.c:376
error_t sshRegisterPasswordChangeCallback(SshContext *context, SshPasswordChangeCallback callback)
Register password change callback function.
Definition: ssh.c:462
error_t sshServerUnregisterChannelOpenCallback(SshServerContext *context, SshChannelOpenCallback callback)
Unregister channel open callback function.
Definition: ssh_server.c:408
SshSignVerifyCallback signVerifyCallback
Signature verification callback.
Definition: ssh_server.h:98
error_t sshServerUnregisterGlobalRequestCallback(SshServerContext *context, SshGlobalReqCallback callback)
Unregister global request callback function.
Definition: ssh_server.c:344
error_t sshRegisterEcdhSharedSecretCalcCallback(SshContext *context, SshEcdhSharedSecretCalcCallback callback)
Register ECDH shared secret calculation callback function.
Definition: ssh.c:586
@ SOCKET_TYPE_STREAM
Definition: socket.h:92
#define OS_SELF_TASK_ID
void sshServerTask(SshServerContext *context)
SSH server task.
Definition: ssh_server.c:794
error_t sshServerInit(SshServerContext *context, const SshServerSettings *settings)
Initialize SSH server context.
Definition: ssh_server.c:124
#define SSH_SERVER_TIMEOUT
Definition: ssh_server.h:51
error_t sshRegisterSignVerifyCallback(SshContext *context, SshSignVerifyCallback callback)
Register signature verification callback function.
Definition: ssh.c:524
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 sshInit(SshContext *context, SshConnection *connections, uint_t numConnections, SshChannel *channels, uint_t numChannels)
SSH context initialization.
Definition: ssh.c:58
error_t sshServerRegisterGlobalRequestCallback(SshServerContext *context, SshGlobalReqCallback callback, void *param)
Register global request callback function.
Definition: ssh_server.c:328
@ ERROR_OPEN_FAILED
Definition: error.h:75
error_t sshUnloadHostKey(SshContext *context, uint_t index)
Unload entity's host key.
Definition: ssh.c:1619
systime_t timeout
Idle connection timeout.
Definition: ssh_server.h:78
void sshServerTick(SshServerContext *context)
Handle periodic operations.
error_t sshRegisterConnectionOpenCallback(SshContext *context, SshConnectionOpenCallback callback, void *param)
Register connection open callback function.
Definition: ssh.c:879
error_t sshServerUnloadHostKey(SshServerContext *context, uint_t index)
Unload server's host key.
Definition: ssh_server.c:584
const IpAddr IP_ADDR_ANY
Definition: ip.c:53
error_t sshUnregisterConnectionCloseCallback(SshContext *context, SshConnectionCloseCallback callback)
Unregister connection close callback function.
Definition: ssh.c:1013
void osDeleteTask(OsTaskId taskId)
Delete a task.
error_t sshRegisterGlobalRequestCallback(SshContext *context, SshGlobalReqCallback callback, void *param)
Register global request callback function.
Definition: ssh.c:618
#define FALSE
Definition: os_port.h:46
systime_t timeout
Idle connection timeout.
Definition: ssh_server.h:123
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t sshServerUnregisterConnectionCloseCallback(SshServerContext *context, SshConnectionCloseCallback callback)
Unregister connection close callback function.
Definition: ssh_server.c:472
error_t sshServerRegisterChannelOpenCallback(SshServerContext *context, SshChannelOpenCallback callback, void *param)
Register channel open callback function.
Definition: ssh_server.c:392
#define SshContext
Definition: ssh.h:870
error_t sshRegisterCaPublicKeyVerifyCallback(SshContext *context, SshCaPublicKeyVerifyCallback callback)
Register CA public key verification callback function.
Definition: ssh.c:338
error_t
Error codes.
Definition: error.h:43
error_t sshRegisterChannelOpenCallback(SshContext *context, SshChannelOpenCallback callback, void *param)
Register channel open callback function.
Definition: ssh.c:792
void sshDeinit(SshContext *context)
Release SSH context.
Definition: ssh.c:2556
error_t sshUnloadCertificate(SshContext *context, uint_t index)
Unload entity's certificate.
Definition: ssh.c:1874
error_t(* SshGlobalReqCallback)(SshConnection *connection, const SshString *name, const uint8_t *data, size_t length, void *param)
Global request callback function.
Definition: ssh.h:1266
bool_t running
Operational state of the SSH server.
Definition: ssh_server.h:116
void sshServerAcceptConnection(SshServerContext *context)
Accept connection request.
void(* OsTaskCode)(void *arg)
Task routine.
uint_t numConnections
Maximum number of SSH connections.
Definition: ssh_server.h:79
@ SSH_OPERATION_MODE_SERVER
Definition: ssh.h:893
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:1282
error_t sshRegisterCertAuthCallback(SshContext *context, SshCertAuthCallback callback)
Register certificate authentication callback function.
Definition: ssh.c:400
error_t sshLoadDhGexGroup(SshContext *context, uint_t index, const char_t *dhParams, size_t dhParamsLen)
Load Diffie-Hellman group.
Definition: ssh.c:1234
@ SOCKET_EVENT_ACCEPT
Definition: socket.h:172
error_t sshUnregisterChannelRequestCallback(SshContext *context, SshChannelReqCallback callback)
Unregister channel request callback function.
Definition: ssh.c:752
SshCaPublicKeyVerifyCallback caPublicKeyVerifyCallback
CA public key verification callback.
Definition: ssh_server.h:90
SSH server context.
Definition: ssh_server.h:115
error_t sshProcessConnectionEvents(SshContext *context, SshConnection *connection)
Connection event handler.
Definition: ssh_misc.c:372
void sshCloseConnection(SshConnection *connection)
Close SSH connection.
Definition: ssh_misc.c:172
const OsTaskParameters OS_TASK_DEFAULT_PARAMS
#define SSH_SERVER_STACK_SIZE
Definition: ssh_server.h:39
OsTaskParameters task
Task parameters.
Definition: ssh_server.h:75
error_t sshServerLoadDhGexGroup(SshServerContext *context, uint_t index, const char_t *dhParams, size_t dhParamsLen)
Load Diffie-Hellman group.
Definition: ssh_server.c:529
void sshServerDeinit(SshServerContext *context)
Release SSH server context.
Definition: ssh_server.c:900
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 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
void * prngContext
Pseudo-random number generator context.
Definition: ssh_server.h:84
#define TRACE_INFO(...)
Definition: debug.h:95
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:125
error_t sshRegisterSignGenCallback(SshContext *context, SshSignGenCallback callback)
Register signature generation callback function.
Definition: ssh.c:493
error_t sshServerUnloadRsaKey(SshServerContext *context, uint_t index)
Unload transient RSA key (for RSA key exchange)
Definition: ssh_server.c:512
#define osEnterTask()
error_t(* SshConnectionOpenCallback)(SshConnection *connection, void *param)
Connection open callback function.
Definition: ssh.h:1291
SshCertAuthCallback certAuthCallback
Certificate authentication callback.
Definition: ssh_server.h:89
@ SSH_CONN_STATE_CLOSED
Definition: ssh.h:1033
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:2149
#define socketBindToInterface
Definition: net_legacy.h:193
error_t sshRegisterEcdhKeyPairGenCallback(SshContext *context, SshEcdhKeyPairGenCallback callback)
Register ECDH key pair generation callback function.
Definition: ssh.c:555
Helper functions for SSH server.
void sshNotifyEvent(SshContext *context)
Notify the SSH context that event is occurring.
Definition: ssh_misc.c:709
error_t sshServerUnloadDhGexGroup(SshServerContext *context, uint_t index)
Unload Diffie-Hellman group.
Definition: ssh_server.c:545
#define SSH_MAX_CONNECTIONS
Definition: ssh.h:185
#define SSH_SERVER_PRIORITY
Definition: ssh_server.h:46
SshKeyLogCallback keyLogCallback
Key logging callback (for debugging purpose only)
Definition: ssh_server.h:105
uint16_t port
SSH port number.
Definition: ssh_server.h:77
@ ERROR_TIMEOUT
Definition: error.h:95
char char_t
Definition: compiler_port.h:48
OsTaskId taskId
Task identifier.
Definition: ssh_server.h:119
error_t sshUnregisterChannelOpenCallback(SshContext *context, SshChannelOpenCallback callback)
Unregister channel open callback function.
Definition: ssh.c:839
SshPasswordChangeCallback passwordChangeCallback
Password change callback.
Definition: ssh_server.h:94
error_t sshSetPrng(SshContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Set the pseudo-random number generator to be used.
Definition: ssh.c:193
void sshRegisterConnectionEvents(SshContext *context, SshConnection *connection, SocketEventDesc *eventDesc)
Register connection events.
Definition: ssh_misc.c:280
#define SshConnection
Definition: ssh.h:874
SSH server.
error_t sshServerUnregisterConnectionOpenCallback(SshServerContext *context, SshConnectionOpenCallback callback)
Unregister connection open callback function.
Definition: ssh_server.c:440
SshConnection * connections
SSH connections.
Definition: ssh_server.h:80
@ ERROR_WAIT_CANCELED
Definition: error.h:73
SSH helper functions.
error_t sshServerUnloadCertificate(SshServerContext *context, uint_t index)
Unload server's certificate.
Definition: ssh_server.c:628
SshContext sshContext
SSH context.
Definition: ssh_server.h:124
SshPasswordAuthCallback passwordAuthCallback
Password authentication callback.
Definition: ssh_server.h:93
error_t sshRegisterPublicKeyAuthCallback(SshContext *context, SshPublicKeyAuthCallback callback)
Register public key authentication callback function.
Definition: ssh.c:369
void osDelayTask(systime_t delay)
Delay routine.
NetInterface * interface
Underlying network interface.
Definition: ssh_server.h:120
uint16_t port
SSH port number.
Definition: ssh_server.h:122
error_t sshServerRegisterConnectionCloseCallback(SshServerContext *context, SshConnectionCloseCallback callback, void *param)
Register connection close callback function.
Definition: ssh_server.c:456
uint_t numChannels
Maximum number of SSH channels.
Definition: ssh_server.h:81
SshSignGenCallback signGenCallback
Signature generation callback.
Definition: ssh_server.h:97
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:135
error_t sshSetOperationMode(SshContext *context, SshOperationMode mode)
Set operation mode (client or server)
Definition: ssh.c:167
error_t sshServerRegisterConnectionOpenCallback(SshServerContext *context, SshConnectionOpenCallback callback, void *param)
Register connection open callback function.
Definition: ssh_server.c:424
error_t sshUnregisterGlobalRequestCallback(SshContext *context, SshGlobalReqCallback callback)
Unregister global request callback function.
Definition: ssh.c:665
Secure Shell (SSH)
const PrngAlgo * prngAlgo
Pseudo-random number generator to be used.
Definition: ssh_server.h:83
SshChannel * channels
SSH channels.
Definition: ssh_server.h:82
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
OsTaskParameters taskParams
Task parameters.
Definition: ssh_server.h:118
@ SOCKET_IP_PROTO_TCP
Definition: socket.h:107
error_t socketSetTimeout(Socket *socket, systime_t timeout)
Set timeout value for blocking operations.
Definition: socket.c:148
Socket * socket
Listening socket.
Definition: ssh_server.h:121
void sshServerGetDefaultSettings(SshServerSettings *settings)
Initialize settings with default values.
Definition: ssh_server.c:50
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_ALREADY_RUNNING
Definition: error.h:293
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
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 sshServerStop(SshServerContext *context)
Stop SSH server.
Definition: ssh_server.c:741
error_t socketListen(Socket *socket, uint_t backlog)
Place a socket in the listening state.
Definition: socket.c:1413