aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ping903q.c152
1 files changed, 100 insertions, 52 deletions
diff --git a/src/ping903q.c b/src/ping903q.c
index 85388f8..a9024c7 100644
--- a/src/ping903q.c
+++ b/src/ping903q.c
@@ -385,9 +385,13 @@ http_query_primitive(char const *meth, char const *url, char **hdr)
static char *std_headers[] = {
"Accept: application/json",
"User-Agent: ping903q (" PACKAGE_STRING ")",
- NULL
+ NULL,
+ NULL,
};
+/* Place where to insert the Authorization header to std_headers */
+#define AUTH_HDR_IDX 2
+
#define BASICPREF "Basic realm=\""
#define BASICLEN (sizeof(BASICPREF)-1)
@@ -478,10 +482,13 @@ machinecmp(char const *pat)
return strcmp(pat, service);
}
+#define HTTP_AUTHORIZATION "Authorization: Basic "
+#define HTTP_AUTHORIZATION_LEN (sizeof(HTTP_AUTHORIZATION)-1)
+
static int
-get_auth_creds(char const *auth, char **retval)
+get_realm_creds(char const *realm, char **retval)
{
- char *realm, *p;
+ char *p;
size_t len;
char const *cfname;
FILE *fp;
@@ -489,32 +496,11 @@ get_auth_creds(char const *auth, char **retval)
int ln = 0;
int skip_to_eol = 0;
int ret;
- int i;
- if (!auth || strncmp(auth, BASICPREF, BASICLEN))
- return -1;
- auth += BASICLEN;
- len = strlen(auth);
- if (len == 0 || auth[len-1] != '"')
- return -1;
- len--;
- if (auth[len-1] == '\\')
- return -1;
- realm = emalloc(len + 1);
- memcpy(realm, auth, len);
- for (i = 0; i < len; ) {
- if (*auth == '\\')
- auth++;
- realm[i++] = *auth++;
- }
- realm[i] = 0;
-
cfname = get_cred_file_name();
fp = fopen(cfname, "r");
- if (!fp) {
- free(realm);
+ if (!fp)
return -1;
- }
ret = -1;
while (fgets(buf, sizeof(buf), fp)) {
@@ -577,11 +563,33 @@ get_auth_creds(char const *auth, char **retval)
&& (strcmp(av[1], "*") == 0
|| strcmp(av[1], realm) == 0)) {
len = strlen(av[2]) + strlen(av[3]) + 2;
- char *p = emalloc(len);
- strcpy(p, av[2]);
- strcat(p, ":");
- strcat(p, av[3]);
- *retval = p;
+ char *plaintext;
+ char *b64;
+ size_t b64_len;
+ char *hdr;
+
+ /* Create plaintext auth string */
+ plaintext = emalloc(len);
+ strcpy(plaintext, av[2]);
+ strcat(plaintext, ":");
+ strcat(plaintext, av[3]);
+
+ /* Encode it to base64 */
+ if (base64_encode(plaintext, len, &b64, &b64_len))
+ emalloc_die();
+
+ free(plaintext);
+
+ /* Create Authorization header */
+ hdr = emalloc(HTTP_AUTHORIZATION_LEN
+ + b64_len
+ + 1);
+ strcpy(hdr, HTTP_AUTHORIZATION);
+ strcat(hdr, b64);
+ free(b64);
+
+ /* Return it */
+ *retval = hdr;
ret = 0;
argcv_free(ac, av);
break;
@@ -591,12 +599,52 @@ get_auth_creds(char const *auth, char **retval)
}
err:
fclose(fp);
- free(realm);
return ret;
}
-#define HTTP_AUTHORIZATION "Authorization: Basic "
-#define HTTP_AUTHORIZATION_LEN (sizeof(HTTP_AUTHORIZATION)-1)
+static int
+get_auth_creds(char const *auth, char **retval)
+{
+ char *realm;
+ size_t len;
+ int rc;
+ int i;
+
+ if (!auth || strncmp(auth, BASICPREF, BASICLEN))
+ return -1;
+ auth += BASICLEN;
+ len = strlen(auth);
+ if (len == 0 || auth[len-1] != '"')
+ return -1;
+ len--;
+ if (auth[len-1] == '\\')
+ return -1;
+ realm = emalloc(len + 1);
+ memcpy(realm, auth, len);
+ for (i = 0; i < len; ) {
+ if (*auth == '\\')
+ auth++;
+ realm[i++] = *auth++;
+ }
+ realm[i] = 0;
+
+ rc = get_realm_creds(realm, retval);
+ free(realm);
+ return rc;
+}
+
+static int
+has_authorization(char **hdr)
+{
+ size_t i;
+ if (!hdr)
+ return 0;
+ for (i = 0; hdr[i]; i++)
+ if (strncmp(hdr[i], HTTP_AUTHORIZATION,
+ HTTP_AUTHORIZATION_LEN) == 0)
+ return 1;
+ return 0;
+}
static void
http_query(char const *meth, char const *url, char **hdr,
@@ -605,17 +653,14 @@ http_query(char const *meth, char const *url, char **hdr,
http_query_primitive(meth, url, hdr);
http_recv(resp);
if (resp->code != 200) {
- if (resp->code == 401) {
+ if (resp->code == 401 && !has_authorization(hdr)) {
char *creds;
char const *auth =
http_resp_get_header(resp,
"WWW-Authenticate");
if (get_auth_creds(auth, &creds) == 0) {
- char *b64creds;
- size_t b64creds_len;
char **new_hdr;
size_t i, nhdr;
- char *auth_hdr;
for (nhdr = 0; hdr[nhdr]; nhdr++)
;
@@ -623,26 +668,14 @@ http_query(char const *meth, char const *url, char **hdr,
sizeof(new_hdr[0]));
for (i = 0; i < nhdr; i++)
new_hdr[i] = hdr[i];
-
- if (base64_encode(creds, strlen(creds),
- &b64creds, &b64creds_len))
- emalloc_die();
- free(creds);
-
- auth_hdr = emalloc(HTTP_AUTHORIZATION_LEN
- + b64creds_len
- + 1);
- strcpy(auth_hdr, HTTP_AUTHORIZATION);
- strcat(auth_hdr, b64creds);
- free(b64creds);
- new_hdr[i] = auth_hdr;
+ new_hdr[i] = creds;
new_hdr[i+1] = NULL;
http_query_primitive(meth, url, new_hdr);
http_recv(resp);
free(new_hdr);
- free(auth_hdr);
+ free(creds);
}
}
}
@@ -997,6 +1030,7 @@ usage(void)
printf("Options:\n\n");
printf(" -f FILE read configuration from FILE\n");
printf(" -h print this help test\n");
+ printf(" -R REALM use credentials for this authentication realm\n");
printf(" -r resolve HOST to IP address\n");
printf(" -V print program version and exit\n");
printf(" -v additional verbosity\n");
@@ -1045,6 +1079,7 @@ main(int argc, char **argv)
char const *host = NULL;
char *c_opt = NULL;
char *w_opt = NULL;
+ char *realm = NULL;
struct nagios_check_data chkdata;
set_progname(argv[0]);
@@ -1059,7 +1094,7 @@ main(int argc, char **argv)
exit(0);
}
}
- while ((c = getopt(argc, argv, "c:f:H:hmp:rVvw:")) != EOF) {
+ while ((c = getopt(argc, argv, "c:f:H:hmp:R:rVvw:")) != EOF) {
switch (c) {
case 'c':
c_opt = optarg;
@@ -1081,6 +1116,9 @@ main(int argc, char **argv)
case 'p':
nagios_prefix_format = optarg;
break;
+ case 'R':
+ realm = optarg;
+ break;
case 'r':
resolve_ip = 1;
break;
@@ -1132,6 +1170,16 @@ main(int argc, char **argv)
http_connect(nodename, service);
free(p);
+ if (realm) {
+ char *auth_hdr;
+ if (get_realm_creds(realm, &auth_hdr) == 0) {
+ std_headers[AUTH_HDR_IDX] = auth_hdr;
+ } else
+ error("can't find credentials for realm %s at %s:%s",
+ realm, nodename, service);
+ }
+
+
switch (mode) {
case MODE_DEFAULT:
switch (argc) {

Return to:

Send suggestions and report system problems to the System administrator.