check_radius.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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. $Id$
  14. ******************************************************************************/
  15. const char *progname = "check_radius";
  16. const char *revision = "$Revision$";
  17. const char *copyright = "2000-2003";
  18. const char *email = "nagiosplug-devel@lists.sourceforge.net";
  19. #include "common.h"
  20. #include "utils.h"
  21. #include "netutils.h"
  22. #include <radiusclient.h>
  23. int process_arguments (int, char **);
  24. void print_help (void);
  25. void print_usage (void);
  26. char *server = NULL;
  27. char *username = NULL;
  28. char *password = NULL;
  29. char *nasid = NULL;
  30. char *expect = NULL;
  31. char *config_file = NULL;
  32. unsigned short port = PW_AUTH_UDP_PORT;
  33. int retries = 1;
  34. int verbose = FALSE;
  35. ENV *env = NULL;
  36. /******************************************************************************
  37. The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
  38. tags in the comments. With in the tags, the XML is assembled sequentially.
  39. You can define entities in tags. You also have all the #defines available as
  40. entities.
  41. Please note that all tags must be lowercase to use the DocBook XML DTD.
  42. @@-<article>
  43. <sect1>
  44. <title>Quick Reference</title>
  45. <!-- The refentry forms a manpage -->
  46. <refentry>
  47. <refmeta>
  48. <manvolnum>5<manvolnum>
  49. </refmeta>
  50. <refnamdiv>
  51. <refname>&progname;</refname>
  52. <refpurpose>&SUMMARY;</refpurpose>
  53. </refnamdiv>
  54. </refentry>
  55. </sect1>
  56. <sect1>
  57. <title>FAQ</title>
  58. </sect1>
  59. <sect1>
  60. <title>Theory, Installation, and Operation</title>
  61. <sect2>
  62. <title>General Description</title>
  63. <para>
  64. &DESCRIPTION;
  65. </para>
  66. </sect2>
  67. <sect2>
  68. <title>Future Enhancements</title>
  69. <para>Todo List</para>
  70. <itemizedlist>
  71. <listitem>Add option to get password from a secured file rather than the command line</listitem>
  72. </itemizedlist>
  73. </sect2>
  74. <sect2>
  75. <title>Functions</title>
  76. -@@
  77. ******************************************************************************/
  78. int
  79. main (int argc, char **argv)
  80. {
  81. UINT4 service;
  82. char msg[BUFFER_LEN];
  83. SEND_DATA data;
  84. int result = STATE_UNKNOWN;
  85. UINT4 client_id;
  86. char *str;
  87. setlocale (LC_ALL, "");
  88. bindtextdomain (PACKAGE, LOCALEDIR);
  89. textdomain (PACKAGE);
  90. if (process_arguments (argc, argv) == ERROR)
  91. usage4 (_("Could not parse arguments"));
  92. str = strdup ("dictionary");
  93. if ((config_file && rc_read_config (config_file)) ||
  94. rc_read_dictionary (rc_conf_str (str)))
  95. die (STATE_UNKNOWN, _("Config file error"));
  96. service = PW_AUTHENTICATE_ONLY;
  97. if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
  98. rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
  99. rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) &&
  100. (nasid==NULL || rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))))
  101. die (STATE_UNKNOWN, _("Out of Memory?"));
  102. /*
  103. * Fill in NAS-IP-Address
  104. */
  105. if ((client_id = rc_own_ipaddress ()) == 0)
  106. return (ERROR_RC);
  107. if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) ==
  108. NULL) return (ERROR_RC);
  109. rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
  110. retries);
  111. result = rc_send_server (&data, msg);
  112. rc_avpair_free (data.send_pairs);
  113. if (data.receive_pairs)
  114. rc_avpair_free (data.receive_pairs);
  115. if (result == TIMEOUT_RC)
  116. die (STATE_CRITICAL, _("Timeout"));
  117. if (result == ERROR_RC)
  118. die (STATE_CRITICAL, _("Auth Error"));
  119. if (result == BADRESP_RC)
  120. die (STATE_WARNING, _("Auth Failed"));
  121. if (expect && !strstr (msg, expect))
  122. die (STATE_WARNING, "%s", msg);
  123. if (result == OK_RC)
  124. die (STATE_OK, _("Auth OK"));
  125. return (0);
  126. }
  127. /* process command-line arguments */
  128. int
  129. process_arguments (int argc, char **argv)
  130. {
  131. int c;
  132. int option = 0;
  133. static struct option longopts[] = {
  134. {"hostname", required_argument, 0, 'H'},
  135. {"port", required_argument, 0, 'P'},
  136. {"username", required_argument, 0, 'u'},
  137. {"password", required_argument, 0, 'p'},
  138. {"nas-id", required_argument, 0, 'n'},
  139. {"filename", required_argument, 0, 'F'},
  140. {"expect", required_argument, 0, 'e'},
  141. {"retries", required_argument, 0, 'r'},
  142. {"timeout", required_argument, 0, 't'},
  143. {"verbose", no_argument, 0, 'v'},
  144. {"version", no_argument, 0, 'V'},
  145. {"help", no_argument, 0, 'h'},
  146. {0, 0, 0, 0}
  147. };
  148. if (argc < 2)
  149. return ERROR;
  150. if (argc == 9) {
  151. config_file = argv[1];
  152. username = argv[2];
  153. password = argv[3];
  154. if (is_intpos (argv[4]))
  155. timeout_interval = atoi (argv[4]);
  156. else
  157. usage2 (_("Timeout interval must be a positive integer"), optarg);
  158. if (is_intpos (argv[5]))
  159. retries = atoi (argv[5]);
  160. else
  161. usage4 (_("Number of retries must be a positive integer"));
  162. server = argv[6];
  163. if (is_intpos (argv[7]))
  164. port = atoi (argv[7]);
  165. else
  166. usage4 (_("Port must be a positive integer"));
  167. expect = argv[8];
  168. return OK;
  169. }
  170. while (1) {
  171. c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:t:r:e:", longopts,
  172. &option);
  173. if (c == -1 || c == EOF || c == 1)
  174. break;
  175. switch (c) {
  176. case '?': /* print short usage statement if args not parsable */
  177. usage2 (_("Unknown argument"), optarg);
  178. case 'h': /* help */
  179. print_help ();
  180. exit (OK);
  181. case 'V': /* version */
  182. print_revision (progname, revision);
  183. exit (OK);
  184. case 'v': /* verbose mode */
  185. verbose = TRUE;
  186. break;
  187. case 'H': /* hostname */
  188. if (is_host (optarg) == FALSE) {
  189. usage2 (_("Invalid hostname/address"), optarg);
  190. }
  191. server = optarg;
  192. break;
  193. case 'P': /* port */
  194. if (is_intnonneg (optarg))
  195. port = atoi (optarg);
  196. else
  197. usage4 (_("Port must be a positive integer"));
  198. break;
  199. case 'u': /* username */
  200. username = optarg;
  201. break;
  202. case 'p': /* password */
  203. password = optarg;
  204. break;
  205. case 'n': /* nas id */
  206. nasid = optarg;
  207. break;
  208. case 'F': /* configuration file */
  209. config_file = optarg;
  210. break;
  211. case 'e': /* expect */
  212. expect = optarg;
  213. break;
  214. case 'r': /* retries */
  215. if (is_intpos (optarg))
  216. retries = atoi (optarg);
  217. else
  218. usage4 (_("Number of retries must be a positive integer"));
  219. break;
  220. case 't': /* timeout */
  221. if (is_intpos (optarg))
  222. timeout_interval = atoi (optarg);
  223. else
  224. usage2 (_("Timeout interval must be a positive integer"), optarg);
  225. break;
  226. }
  227. }
  228. return OK;
  229. }
  230. void
  231. print_help (void)
  232. {
  233. char *myport;
  234. asprintf (&myport, "%d", PW_AUTH_UDP_PORT);
  235. print_revision (progname, revision);
  236. printf ("Copyright (c) 1999 Robert August Vincent II\n");
  237. printf (COPYRIGHT, copyright, email);
  238. printf(_("Tests to see if a radius server is accepting connections.\n\n"));
  239. print_usage ();
  240. printf (_(UT_HELP_VRSN));
  241. printf (_(UT_HOST_PORT), 'P', myport);
  242. printf (_("\
  243. -u, --username=STRING\n\
  244. The user to authenticate\n\
  245. -p, --password=STRING\n\
  246. Password for autentication (SECURITY RISK)\n\
  247. -n, --nas-id=STRING\n\
  248. NAS identifier\n\
  249. -F, --filename=STRING\n\
  250. Configuration file\n\
  251. -e, --expect=STRING\n\
  252. Response string to expect from the server\n\
  253. -r, --retries=INTEGER\n\
  254. Number of times to retry a failed connection\n"));
  255. printf (_(UT_TIMEOUT), timeout_interval);
  256. printf (_("\n\
  257. This plugin tests a radius server to see if it is accepting connections.\n\
  258. \n\
  259. The server to test must be specified in the invocation, as well as a user\n\
  260. name and password. A configuration file may also be present. The format of\n\
  261. the configuration file is described in the radiusclient library sources.\n\n"));
  262. printf (_("\
  263. The password option presents a substantial security issue because the\n\
  264. password can be determined by careful watching of the command line in\n\
  265. a process listing. This risk is exacerbated because nagios will\n\
  266. run the plugin at regular prdictable intervals. Please be sure that\n\
  267. the password used does not allow access to sensitive system resources,\n\
  268. otherwise compormise could occur.\n"));
  269. printf (_(UT_SUPPORT));
  270. }
  271. void
  272. print_usage (void)
  273. {
  274. printf ("\
  275. Usage: %s -H host -F config_file -u username -p password [-n nas-id] [-P port]\n\
  276. [-t timeout] [-r retries] [-e expect]\n", progname);
  277. }