check_ssh.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * check_ssh.c
  3. *
  4. * Made by (Remi PAULMIER)
  5. * Login <remi@sinfomic.fr>
  6. *
  7. * Started on Fri Jul 9 09:18:23 1999 Remi PAULMIER
  8. * Update Thu Jul 22 12:50:04 1999 remi paulmier
  9. * $Id$
  10. *
  11. */
  12. #include "config.h"
  13. #include "common.h"
  14. #include "netutils.h"
  15. #include "utils.h"
  16. #define PROGNAME "check_ssh"
  17. #ifndef MSG_DONTWAIT
  18. #define MSG_DONTWAIT 0
  19. #endif
  20. #define SSH_DFL_PORT 22
  21. #define BUFF_SZ 256
  22. short port = -1;
  23. char *server_name = NULL;
  24. int verbose = FALSE;
  25. int process_arguments (int, char **);
  26. int call_getopt (int, char **);
  27. int validate_arguments (void);
  28. void print_help (void);
  29. void print_usage (void);
  30. char *ssh_resolve (char *hostname);
  31. int ssh_connect (char *haddr, short hport);
  32. int
  33. main (int argc, char **argv)
  34. {
  35. if (process_arguments (argc, argv) == ERROR)
  36. usage ("Could not parse arguments\n");
  37. /* initialize alarm signal handling */
  38. signal (SIGALRM, socket_timeout_alarm_handler);
  39. alarm (socket_timeout);
  40. /* ssh_connect exits if error is found */
  41. ssh_connect (ssh_resolve (server_name), port);
  42. alarm (0);
  43. return (STATE_OK);
  44. }
  45. /* process command-line arguments */
  46. int
  47. process_arguments (int argc, char **argv)
  48. {
  49. int c;
  50. if (argc < 2)
  51. return ERROR;
  52. for (c = 1; c < argc; c++)
  53. if (strcmp ("-to", argv[c]) == 0)
  54. strcpy (argv[c], "-t");
  55. c = 0;
  56. while (c += (call_getopt (argc - c, &argv[c]))) {
  57. if (argc <= c)
  58. break;
  59. if (server_name == NULL) {
  60. server_name = argv[c];
  61. }
  62. else if (port == -1) {
  63. if (is_intpos (argv[c])) {
  64. port = atoi (argv[c]);
  65. }
  66. else {
  67. print_usage ();
  68. exit (STATE_UNKNOWN);
  69. }
  70. }
  71. }
  72. return validate_arguments ();
  73. }
  74. /************************************************************************
  75. *
  76. * Run the getopt until we encounter a non-option entry in the arglist
  77. *
  78. *-----------------------------------------------------------------------*/
  79. int
  80. call_getopt (int argc, char **argv)
  81. {
  82. int c, i = 1;
  83. #ifdef HAVE_GETOPT_H
  84. int option_index = 0;
  85. static struct option long_options[] = {
  86. {"version", no_argument, 0, 'V'},
  87. {"help", no_argument, 0, 'h'},
  88. {"verbose", no_argument, 0, 'v'},
  89. {"timeout", required_argument, 0, 't'},
  90. {"host", required_argument, 0, 'H'},
  91. {0, 0, 0, 0}
  92. };
  93. #endif
  94. while (1) {
  95. #ifdef HAVE_GETOPT_H
  96. c = getopt_long (argc, argv, "+Vhvt:H:p:", long_options, &option_index);
  97. #else
  98. c = getopt (argc, argv, "+Vhvt:H:p:");
  99. #endif
  100. if (c == -1 || c == EOF)
  101. break;
  102. i++;
  103. switch (c) {
  104. case 't':
  105. case 'H':
  106. case 'p':
  107. i++;
  108. }
  109. switch (c) {
  110. case '?': /* help */
  111. usage ("");
  112. case 'V': /* version */
  113. print_revision (my_basename (argv[0]), "$Revision$");
  114. exit (STATE_OK);
  115. case 'h': /* help */
  116. print_help ();
  117. exit (STATE_OK);
  118. case 'v': /* verose */
  119. verbose = TRUE;
  120. break;
  121. case 't': /* timeout period */
  122. if (!is_integer (optarg))
  123. usage ("Timeout Interval must be an integer!\n\n");
  124. socket_timeout = atoi (optarg);
  125. break;
  126. case 'H': /* host */
  127. server_name = optarg;
  128. break;
  129. case 'p': /* port */
  130. if (is_intpos (optarg)) {
  131. port = atoi (optarg);
  132. }
  133. else {
  134. printf ("Port number nust be a positive integer: %s\n", optarg);
  135. usage ("");
  136. }
  137. }
  138. }
  139. return i;
  140. }
  141. int
  142. validate_arguments (void)
  143. {
  144. if (server_name == NULL)
  145. return ERROR;
  146. if (port == -1) /* funky, but allows -p to override stray integer in args */
  147. port = SSH_DFL_PORT;
  148. return OK;
  149. }
  150. /************************************************************************
  151. *
  152. * Resolve hostname into IP address
  153. *
  154. *-----------------------------------------------------------------------*/
  155. char *
  156. ssh_resolve (char *hostname)
  157. {
  158. struct hostent *host;
  159. host = gethostbyname (hostname);
  160. if (!host) {
  161. herror (hostname);
  162. exit (STATE_CRITICAL);
  163. }
  164. return (host->h_addr);
  165. }
  166. /************************************************************************
  167. *
  168. * Try to connect to SSH server at specified server and port
  169. *
  170. *-----------------------------------------------------------------------*/
  171. int
  172. ssh_connect (char *haddr, short hport)
  173. {
  174. int s;
  175. struct sockaddr_in addr;
  176. int addrlen;
  177. int len;
  178. char *output = NULL;
  179. char *buffer = NULL;
  180. char *ssh_proto = NULL;
  181. char *ssh_server = NULL;
  182. char revision[20];
  183. sscanf ("$Revision$", "$Revision: %[0123456789.]", revision);
  184. addrlen = sizeof (addr);
  185. memset (&addr, 0, addrlen);
  186. addr.sin_port = htons (hport);
  187. addr.sin_family = AF_INET;
  188. bcopy (haddr, (void *) &addr.sin_addr.s_addr, 4);
  189. s = socket (AF_INET, SOCK_STREAM, 0);
  190. if (!s) {
  191. printf ("socket(): %s for %s:%d\n", strerror (errno), server_name, hport);
  192. exit (STATE_CRITICAL);
  193. }
  194. if (connect (s, (struct sockaddr *) &addr, addrlen)) {
  195. printf ("connect(): %s for %s:%d\n", strerror (errno), server_name,
  196. hport);
  197. exit (STATE_CRITICAL);
  198. }
  199. output = (char *) malloc (BUFF_SZ + 1);
  200. memset (output, 0, BUFF_SZ + 1);
  201. recv (s, output, BUFF_SZ, 0);
  202. if (strncmp (output, "SSH", 3)) {
  203. printf ("Server answer: %s", output);
  204. exit (STATE_CRITICAL);
  205. }
  206. else {
  207. strip (output);
  208. if (verbose)
  209. printf ("%s\n", output);
  210. ssh_proto = output + 4;
  211. ssh_server = ssh_proto + strspn (ssh_proto, "0123456789-. ");
  212. ssh_proto[strspn (ssh_proto, "0123456789-. ")] = 0;
  213. printf
  214. ("SSH ok - protocol version %s - server version %s\n",
  215. ssh_proto, ssh_server);
  216. buffer =
  217. ssprintf (buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, revision);
  218. send (s, buffer, strlen (buffer), MSG_DONTWAIT);
  219. if (verbose)
  220. printf ("%s\n", buffer);
  221. exit (STATE_OK);
  222. }
  223. }
  224. void
  225. print_help (void)
  226. {
  227. print_revision (PROGNAME, "$Revision$");
  228. printf ("Copyright (c) 1999 Remi Paulmier (remi@sinfomic.fr)\n\n");
  229. print_usage ();
  230. printf ("by default, port is %d\n", SSH_DFL_PORT);
  231. }
  232. void
  233. print_usage (void)
  234. {
  235. printf
  236. ("Usage:\n"
  237. " %s -t [timeout] -p [port] <host>\n"
  238. " %s -V prints version info\n"
  239. " %s -h prints more detailed help\n", PROGNAME, PROGNAME, PROGNAME);
  240. }
  241. /* end of check_ssh.c */