check_ssh.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /******************************************************************************
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13. ******************************************************************************/
  14. #include "common.h"
  15. #include "netutils.h"
  16. #include "utils.h"
  17. const char *progname = "check_ssh";
  18. const char *revision = "$Revision$";
  19. const char *copyright = "2000-2003";
  20. const char *email = "nagiosplug-devel@lists.sourceforge.net";
  21. #ifndef MSG_DONTWAIT
  22. #define MSG_DONTWAIT 0
  23. #endif
  24. #define SSH_DFL_PORT 22
  25. #define BUFF_SZ 256
  26. int port = -1;
  27. char *server_name = NULL;
  28. int verbose = FALSE;
  29. int process_arguments (int, char **);
  30. int validate_arguments (void);
  31. void print_help (void);
  32. void print_usage (void);
  33. int ssh_connect (char *haddr, int hport);
  34. int
  35. main (int argc, char **argv)
  36. {
  37. int result;
  38. setlocale (LC_ALL, "");
  39. bindtextdomain (PACKAGE, LOCALEDIR);
  40. textdomain (PACKAGE);
  41. if (process_arguments (argc, argv) == ERROR)
  42. usage (_("Could not parse arguments\n"));
  43. /* initialize alarm signal handling */
  44. signal (SIGALRM, socket_timeout_alarm_handler);
  45. alarm (socket_timeout);
  46. /* ssh_connect exits if error is found */
  47. result = ssh_connect (server_name, port);
  48. alarm (0);
  49. return (result);
  50. }
  51. /* process command-line arguments */
  52. int
  53. process_arguments (int argc, char **argv)
  54. {
  55. int c;
  56. int option = 0;
  57. static struct option longopts[] = {
  58. {"help", no_argument, 0, 'h'},
  59. {"version", no_argument, 0, 'V'},
  60. {"host", required_argument, 0, 'H'},
  61. {"port", required_argument, 0, 'p'},
  62. {"use-ipv4", no_argument, 0, '4'},
  63. {"use-ipv6", no_argument, 0, '6'},
  64. {"timeout", required_argument, 0, 't'},
  65. {"verbose", no_argument, 0, 'v'},
  66. {0, 0, 0, 0}
  67. };
  68. if (argc < 2)
  69. return ERROR;
  70. for (c = 1; c < argc; c++)
  71. if (strcmp ("-to", argv[c]) == 0)
  72. strcpy (argv[c], "-t");
  73. while (1) {
  74. c = getopt_long (argc, argv, "+Vhv46t:H:p:", longopts, &option);
  75. if (c == -1 || c == EOF)
  76. break;
  77. switch (c) {
  78. case '?': /* help */
  79. usage ("");
  80. case 'V': /* version */
  81. print_revision (progname, revision);
  82. exit (STATE_OK);
  83. case 'h': /* help */
  84. print_help ();
  85. exit (STATE_OK);
  86. case 'v': /* verose */
  87. verbose = TRUE;
  88. break;
  89. case 't': /* timeout period */
  90. if (!is_integer (optarg))
  91. usage (_("Timeout Interval must be an integer!\n\n"));
  92. else
  93. socket_timeout = atoi (optarg);
  94. break;
  95. case '4':
  96. address_family = AF_INET;
  97. break;
  98. case '6':
  99. #ifdef USE_IPV6
  100. address_family = AF_INET6;
  101. #else
  102. usage (_("IPv6 support not available\n"));
  103. #endif
  104. break;
  105. case 'H': /* host */
  106. if (is_host (optarg) == FALSE)
  107. usage ("Invalid hostname/address\n");
  108. server_name = optarg;
  109. break;
  110. case 'p': /* port */
  111. if (is_intpos (optarg)) {
  112. port = atoi (optarg);
  113. }
  114. else {
  115. printf ("Port number nust be a positive integer: %s\n", optarg);
  116. usage ("");
  117. }
  118. }
  119. }
  120. c = optind;
  121. if (server_name == NULL && c < argc) {
  122. if (is_host (argv[c])) {
  123. server_name = argv[c++];
  124. }
  125. }
  126. if (port == -1 && c < argc) {
  127. if (is_intpos (argv[c])) {
  128. port = atoi (argv[c++]);
  129. }
  130. else {
  131. print_usage ();
  132. exit (STATE_UNKNOWN);
  133. }
  134. }
  135. return validate_arguments ();
  136. }
  137. int
  138. validate_arguments (void)
  139. {
  140. if (server_name == NULL)
  141. return ERROR;
  142. if (port == -1) /* funky, but allows -p to override stray integer in args */
  143. port = SSH_DFL_PORT;
  144. return OK;
  145. }
  146. /************************************************************************
  147. *
  148. * Try to connect to SSH server at specified server and port
  149. *
  150. *-----------------------------------------------------------------------*/
  151. int
  152. ssh_connect (char *haddr, int hport)
  153. {
  154. int sd;
  155. int result;
  156. char *output = NULL;
  157. char *buffer = NULL;
  158. char *ssh_proto = NULL;
  159. char *ssh_server = NULL;
  160. char rev_no[20];
  161. sscanf ("$Revision$", "$Revision: %[0123456789.]", rev_no);
  162. result = my_tcp_connect (haddr, hport, &sd);
  163. if (result != STATE_OK)
  164. return result;
  165. output = (char *) malloc (BUFF_SZ + 1);
  166. memset (output, 0, BUFF_SZ + 1);
  167. recv (sd, output, BUFF_SZ, 0);
  168. if (strncmp (output, "SSH", 3)) {
  169. printf (_("Server answer: %s"), output);
  170. exit (STATE_CRITICAL);
  171. }
  172. else {
  173. strip (output);
  174. if (verbose)
  175. printf ("%s\n", output);
  176. ssh_proto = output + 4;
  177. ssh_server = ssh_proto + strspn (ssh_proto, "-0123456789. ");
  178. ssh_proto[strspn (ssh_proto, "0123456789. ")] = 0;
  179. printf
  180. (_("SSH OK - %s (protocol %s)\n"),
  181. ssh_server, ssh_proto);
  182. asprintf (&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no);
  183. send (sd, buffer, strlen (buffer), MSG_DONTWAIT);
  184. if (verbose)
  185. printf ("%s\n", buffer);
  186. exit (STATE_OK);
  187. }
  188. }
  189. void
  190. print_help (void)
  191. {
  192. char *myport;
  193. asprintf (&myport, "%d", SSH_DFL_PORT);
  194. print_revision (progname, revision);
  195. printf (_("Copyright (c) 1999 Remi Paulmier <remi@sinfomic.fr>\n"));
  196. printf (_(COPYRIGHT), copyright, email);
  197. printf (_("Try to connect to SSH server at specified server and port\n\n"));
  198. print_usage ();
  199. printf (_(UT_HELP_VRSN));
  200. printf (_(UT_HOST_PORT), 'p', myport);
  201. printf (_(UT_IPv46));
  202. printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
  203. printf (_(UT_VERBOSE));
  204. printf (_(UT_SUPPORT));
  205. }
  206. void
  207. print_usage (void)
  208. {
  209. printf (_("\
  210. Usage: %s [-46] [-t <timeout>] [-p <port>] <host>\n"), progname);
  211. printf (_(UT_HLP_VRS), progname, progname);
  212. }
  213. /* end of check_ssh.c */