]>
git.ipfire.org Git - thirdparty/squid.git/blob - tools/cachemgr.cc
3 * $Id: cachemgr.cc,v 1.1 2006/05/11 01:36:57 hno Exp $
5 * DEBUG: section 0 CGI Cache Manager
6 * AUTHOR: Duane Wessels
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
48 #include <sys/types.h>
63 #include <gnumalloc.h>
70 #if HAVE_NETDB_H && !defined(_SQUID_NETDB_H_) /* protect NEXTSTEP */
71 #define _SQUID_NETDB_H_
84 #include <sys/param.h>
89 #if HAVE_SYS_RESOURCE_H
90 #include <sys/resource.h> /* needs sys/time.h above it */
93 #include <sys/socket.h>
96 #include <netinet/in.h>
99 #include <arpa/inet.h>
102 #include <sys/stat.h>
108 #include <sys/wait.h>
125 #if HAVE_SYS_SELECT_H
126 #include <sys/select.h>
139 #include "snprintf.h"
141 #ifndef DEFAULT_CACHEMGR_CONFIG
142 #define DEFAULT_CACHEMGR_CONFIG "/etc/squid/cachemgr.conf"
159 * Debugging macros (info goes to error_log on your web server)
160 * Note: do not run cache manager with non zero debugging level
161 * if you do not debug, it may write a lot of [sensitive]
162 * information to your error log.
165 /* debugging level 0 (disabled) - 3 (max) */
166 #define DEBUG_LEVEL 0
167 #define debug(level) if ((level) <= DEBUG_LEVEL && DEBUG_LEVEL > 0)
170 * Static variables and constants
172 static const time_t passwd_ttl
= 60 * 60 * 3; /* in sec */
173 static const char *script_name
= "/cgi-bin/cachemgr.cgi";
174 static const char *progname
= NULL
;
177 static struct IN_ADDR no_addr
;
180 * Function prototypes
182 #define safe_free(str) { if (str) { xfree(str); (str) = NULL; } }
183 static const char *safe_str(const char *str
);
184 static const char *xstrtok(char **str
, char del
);
185 static void print_trailer(void);
186 static void auth_html(const char *host
, int port
, const char *user_name
);
187 static void error_html(const char *msg
);
188 static char *menu_url(cachemgr_request
* req
, const char *action
);
189 static int parse_status_line(const char *sline
, const char **statusStr
);
191 static cachemgr_request
*read_request(char *);
193 static cachemgr_request
*read_request(void);
195 static char *read_get_request(void);
196 static char *read_post_request(void);
198 static void make_pub_auth(cachemgr_request
* req
);
199 static void decode_pub_auth(cachemgr_request
* req
);
200 static void reset_auth(cachemgr_request
* req
);
201 static const char *make_auth_header(const cachemgr_request
* req
);
203 static int check_target_acl(const char *hostname
, int port
);
206 static int s_iInitCount
= 0;
207 int Win32SockInit(void)
209 int iVersionRequested
;
213 if (s_iInitCount
> 0) {
216 } else if (s_iInitCount
< 0)
217 return (s_iInitCount
);
219 /* s_iInitCount == 0. Do the initailization */
220 iVersionRequested
= MAKEWORD(2, 0);
222 err
= WSAStartup((WORD
) iVersionRequested
, &wsaData
);
226 return (s_iInitCount
);
229 if (LOBYTE(wsaData
.wVersion
) != 2 ||
230 HIBYTE(wsaData
.wVersion
) != 0) {
233 return (s_iInitCount
);
237 return (s_iInitCount
);
240 void Win32SockCleanup(void)
242 if (--s_iInitCount
== 0)
248 #endif /* ifdef _SQUID_MSWIN_ */
251 safe_str(const char *str
)
253 return str
? str
: "";
256 /* relaxed number format */
258 is_number(const char *str
)
260 return strspn(str
, "\t -+01234567890./\n") == strlen(str
);
264 xstrtok(char **str
, char del
)
267 char *p
= strchr(*str
, del
);
280 while (len
&& xisspace(tok
[len
- 1]))
283 while (xisspace(*tok
))
294 printf("<HR noshade size=\"1px\">\n");
295 printf("<ADDRESS>\n");
296 printf("Generated %s, by %s/%s@%s\n",
297 mkrfc1123(now
), progname
, VERSION
, getfullhostname());
298 printf("</ADDRESS></BODY></HTML>\n");
302 auth_html(const char *host
, int port
, const char *user_name
)
310 if (!host
|| !strlen(host
))
313 printf("Content-Type: text/html\r\n\r\n");
315 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
317 printf("<HTML><HEAD><TITLE>Cache Manager Interface</TITLE>\n");
319 printf("<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}--></STYLE></HEAD>\n");
321 printf("<BODY><H1>Cache Manager Interface</H1>\n");
323 printf("<P>This is a WWW interface to the instrumentation interface\n");
325 printf("for the Squid object cache.</P>\n");
327 printf("<HR noshade size=\"1px\">\n");
329 printf("<FORM METHOD=\"POST\" ACTION=\"%s\">\n", script_name
);
331 printf("<TABLE BORDER=\"0\" CELLPADDING=\"10\" CELLSPACING=\"1\">\n");
334 fp
= fopen("cachemgr.conf", "r");
337 fp
= fopen(DEFAULT_CACHEMGR_CONFIG
, "r");
341 char config_line
[BUFSIZ
];
343 while (fgets(config_line
, BUFSIZ
, fp
)) {
344 char *server
, *comment
;
345 strtok(config_line
, "\r\n");
347 if (config_line
[0] == '#')
350 if (config_line
[0] == '\0')
353 if ((server
= strtok(config_line
, " \t")) == NULL
)
356 if (strchr(server
, '*') || strchr(server
, '[') || strchr(server
, '?')) {
361 comment
= strtok(NULL
, "");
364 while (*comment
== ' ' || *comment
== '\t')
367 if (!comment
|| !*comment
)
371 printf("<TR><TH ALIGN=\"left\">Cache Server:</TH><TD><SELECT NAME=\"server\">\n");
374 printf("<OPTION VALUE=\"%s\"%s>%s</OPTION>\n", server
, (servers
|| *host
) ? "" : " SELECTED", comment
);
379 if (need_host
== 1 && !*host
)
383 printf("<OPTION VALUE=\"\"%s>Other</OPTION>\n", (*host
) ? " SELECTED" : "");
385 printf("</SELECT></TR>\n");
392 if (need_host
== 1 && !*host
)
395 printf("<TR><TH ALIGN=\"left\">Cache Host:</TH><TD><INPUT NAME=\"host\" ");
397 printf("size=\"30\" VALUE=\"%s\"></TD></TR>\n", host
);
399 printf("<TR><TH ALIGN=\"left\">Cache Port:</TH><TD><INPUT NAME=\"port\" ");
401 printf("size=\"30\" VALUE=\"%d\"></TD></TR>\n", port
);
404 printf("<TR><TH ALIGN=\"left\">Manager name:</TH><TD><INPUT NAME=\"user_name\" ");
406 printf("size=\"30\" VALUE=\"%s\"></TD></TR>\n", user_name
);
408 printf("<TR><TH ALIGN=\"left\">Password:</TH><TD><INPUT TYPE=\"password\" NAME=\"passwd\" ");
410 printf("size=\"30\" VALUE=\"\"></TD></TR>\n");
412 printf("</TABLE><BR CLEAR=\"all\">\n");
414 printf("<INPUT TYPE=\"submit\" VALUE=\"Continue...\">\n");
422 error_html(const char *msg
)
424 printf("Content-Type: text/html\r\n\r\n");
425 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
426 printf("<HTML><HEAD><TITLE>Cache Manager Error</TITLE>\n");
427 printf("<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}--></STYLE></HEAD>\n");
428 printf("<BODY><H1>Cache Manager Error</H1>\n");
429 printf("<P>\n%s</P>\n", msg
);
433 /* returns http status extracted from status line or -1 on parsing failure */
435 parse_status_line(const char *sline
, const char **statusStr
)
437 const char *sp
= strchr(sline
, ' ');
442 if (strncasecmp(sline
, "HTTP/", 5) || !sp
)
445 while (xisspace(*++sp
))
458 menu_url(cachemgr_request
* req
, const char *action
)
460 static char url
[1024];
461 snprintf(url
, sizeof(url
), "%s?host=%s&port=%d&user_name=%s&operation=%s&auth=%s",
465 safe_str(req
->user_name
),
467 safe_str(req
->pub_auth
));
472 munge_menu_line(const char *buf
, cachemgr_request
* req
)
480 static char html
[2 * 1024];
488 buf_copy
= x
= xstrdup(buf
);
490 a
= xstrtok(&x
, '\t');
492 d
= xstrtok(&x
, '\t');
494 p
= xstrtok(&x
, '\t');
496 a_url
= xstrdup(menu_url(req
, a
));
498 /* no reason to give a url for a disabled action */
499 if (!strcmp(p
, "disabled"))
500 snprintf(html
, sizeof(html
), "<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d
, a_url
);
502 /* disable a hidden action (requires a password, but password is not in squid.conf) */
503 if (!strcmp(p
, "hidden"))
504 snprintf(html
, sizeof(html
), "<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d
, a_url
);
506 /* disable link if authentication is required and we have no password */
507 if (!strcmp(p
, "protected") && !req
->passwd
)
508 snprintf(html
, sizeof(html
), "<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
509 d
, menu_url(req
, "authenticate"), a_url
);
511 /* highlight protected but probably available entries */
512 if (!strcmp(p
, "protected"))
513 snprintf(html
, sizeof(html
), "<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n",
516 /* public entry or unknown type of protection */
518 snprintf(html
, sizeof(html
), "<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url
, d
);
528 munge_other_line(const char *buf
, cachemgr_request
* req
)
530 static const char *ttags
[] = {"td", "th"};
532 static char html
[4096];
533 static int table_line_num
= 0;
534 static int next_is_header
= 0;
540 /* does it look like a table? */
542 if (!strchr(buf
, '\t') || *buf
== '\t') {
543 /* nope, just text */
544 snprintf(html
, sizeof(html
), "%s%s",
545 table_line_num
? "</table>\n<pre>" : "", buf
);
550 /* start html table */
551 if (!table_line_num
) {
552 l
+= snprintf(html
+ l
, sizeof(html
) - l
, "</pre><table cellpadding=\"2\" cellspacing=\"1\">\n");
557 is_header
= (!table_line_num
|| next_is_header
) && !strchr(buf
, ':') && !is_number(buf
);
559 ttag
= ttags
[is_header
];
562 l
+= snprintf(html
+ l
, sizeof(html
) - l
, "<tr>");
564 /* substitute '\t' */
565 buf_copy
= x
= xstrdup(buf
);
567 if ((p
= strchr(x
, '\n')))
570 while (x
&& strlen(x
)) {
572 const char *cell
= xstrtok(&x
, '\t');
574 while (x
&& *x
== '\t') {
579 l
+= snprintf(html
+ l
, sizeof(html
) - l
, "<%s colspan=\"%d\" align=\"%s\">%s</%s>",
581 is_header
? "center" : is_number(cell
) ? "right" : "left",
587 l
+= snprintf(html
+ l
, sizeof(html
) - l
, "</tr>\n");
588 next_is_header
= is_header
&& strstr(buf
, "\t\t");
594 read_reply(int s
, cachemgr_request
* req
)
600 FILE *fp
= tmpfile();
603 FILE *fp
= fdopen(s
, "r");
605 /* interpretation states */
607 isStatusLine
, isHeaders
, isBodyStart
, isBody
, isForward
, isEof
, isForwardEof
, isSuccess
, isError
608 } istate
= isStatusLine
;
610 const char *action
= req
->action
;
611 const char *statusStr
= NULL
;
614 if (0 == strlen(req
->action
))
616 else if (0 == strcasecmp(req
->action
, "menu"))
626 while ((reply
=recv(s
, buf
, sizeof(buf
), 0)) > 0)
627 fwrite(buf
, 1, reply
, fp
);
636 /* read reply interpreting one line at a time depending on state */
637 while (istate
< isEof
) {
638 if (!fgets(buf
, sizeof(buf
), fp
))
639 istate
= istate
== isForward
? isForwardEof
: isEof
;
644 /* get HTTP status */
645 /* uncomment the following if you want to debug headers */
646 /* fputs("\r\n\r\n", stdout); */
647 status
= parse_status_line(buf
, &statusStr
);
648 istate
= status
== 200 ? isHeaders
: isForward
;
649 /* if cache asks for authentication, we have to reset our info */
651 if (status
== 401 || status
== 407) {
653 status
= 403; /* Forbiden, see comments in case isForward: */
656 /* this is a way to pass HTTP status to the Web server */
658 printf("Status: %d %s", status
, statusStr
); /* statusStr has '\n' */
663 /* forward header field */
664 if (!strcmp(buf
, "\r\n")) { /* end of headers */
665 fputs("Content-Type: text/html\r\n", stdout
); /* add our type */
666 istate
= isBodyStart
;
669 if (strncasecmp(buf
, "Content-Type:", 13)) /* filter out their type */
675 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
677 printf("<HTML><HEAD><TITLE>CacheMgr@%s: %s</TITLE>\n",
678 req
->hostname
, action
);
680 printf("<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}TABLE{background-color:#333333;border:0pt;padding:0pt}TH,TD{background-color:#ffffff;white-space:nowrap}--></STYLE>\n");
682 printf("</HEAD><BODY>\n");
685 printf("<H2><a href=\"%s\">Cache Manager</a> menu for %s:</H2>",
686 menu_url(req
, "authenticate"), req
->hostname
);
689 printf("<P><A HREF=\"%s\">%s</A>\n<HR noshade size=\"1px\">\n",
690 menu_url(req
, "menu"), "Cache Manager menu");
695 /* yes, fall through, we do not want to loose the first line */
698 /* interpret [and reformat] cache response */
701 fputs(munge_menu_line(buf
, req
), stdout
);
703 fputs(munge_other_line(buf
, req
), stdout
);
708 /* forward: no modifications allowed */
710 * Note: we currently do not know any way to get browser.reply to
711 * 401 to .cgi because web server filters out all auth info. Thus we
712 * disable authentication headers for now.
714 if (!strncasecmp(buf
, "WWW-Authenticate:", 17) || !strncasecmp(buf
, "Proxy-Authenticate:", 19))
727 printf("</table></PRE>\n");
736 /* indicate that we finished processing an "error" sequence */
742 printf("%s: internal bug: invalid state reached: %d", script_name
, istate
);
753 process_request(cachemgr_request
* req
)
756 const struct hostent
*hp
;
758 static struct sockaddr_in S
;
766 static char buf
[2 * 1024];
769 auth_html(CACHEMGR_HOSTNAME
, CACHE_HTTP_PORT
, "");
773 if (req
->hostname
== NULL
) {
774 req
->hostname
= xstrdup(CACHEMGR_HOSTNAME
);
777 if (req
->port
== 0) {
778 req
->port
= CACHE_HTTP_PORT
;
781 if (req
->action
== NULL
) {
782 req
->action
= xstrdup("");
785 if (strcmp(req
->action
, "authenticate") == 0) {
786 auth_html(req
->hostname
, req
->port
, req
->user_name
);
790 if (!check_target_acl(req
->hostname
, req
->port
)) {
791 snprintf(buf
, 1024, "target %s:%d not allowed in cachemgr.conf\n", req
->hostname
, req
->port
);
796 if ((s
= socket(PF_INET
, SOCK_STREAM
, 0)) < 0) {
797 snprintf(buf
, 1024, "socket: %s\n", xstrerror());
802 memset(&S
, '\0', sizeof(S
));
803 S
.sin_family
= AF_INET
;
805 if ((hp
= gethostbyname(req
->hostname
)) != NULL
) {
806 assert(hp
->h_length
>= 0 && (size_t)hp
->h_length
<= sizeof(S
.sin_addr
.s_addr
));
807 xmemcpy(&S
.sin_addr
.s_addr
, hp
->h_addr
, hp
->h_length
);
808 } else if (safe_inet_addr(req
->hostname
, &S
.sin_addr
))
811 snprintf(buf
, 1024, "Unknown host: %s\n", req
->hostname
);
816 S
.sin_port
= htons(req
->port
);
818 if (connect(s
, (struct sockaddr
*) &S
, sizeof(S
)) < 0) {
819 snprintf(buf
, 1024, "connect %s:%d: %s\n",
820 inet_ntoa(S
.sin_addr
),
827 l
= snprintf(buf
, sizeof(buf
),
828 "GET cache_object://%s/%s HTTP/1.0\r\n"
830 "%s" /* Authentication info or nothing */
834 make_auth_header(req
));
836 debug(1) fprintf(stderr
, "wrote request: '%s'\n", buf
);
839 answer
=read_reply(s
, req
);
844 return read_reply(s
, req
);
849 main(int argc
, char *argv
[])
852 cachemgr_request
*req
;
858 safe_inet_addr("255.255.255.255", &no_addr
);
864 _setmode( _fileno( stdin
), _O_BINARY
);
865 _setmode( _fileno( stdout
), _O_BINARY
);
868 if ((s
= strrchr(argv
[0], '\\')))
871 if ((s
= strrchr(argv
[0], '/')))
874 progname
= xstrdup(s
+ 1);
876 progname
= xstrdup(argv
[0]);
878 if ((s
= getenv("SCRIPT_NAME")) != NULL
)
879 script_name
= xstrdup(s
);
883 req
= read_request(NULL
);
885 answer
=process_request(req
);
893 req
= read_request();
895 return process_request(req
);
901 read_post_request(void)
907 if ((s
= getenv("REQUEST_METHOD")) == NULL
)
910 if (0 != strcasecmp(s
, "POST"))
913 if ((s
= getenv("CONTENT_LENGTH")) == NULL
)
916 if ((len
= atoi(s
)) <= 0)
919 buf
= (char *)xmalloc(len
+ 1);
921 fread(buf
, len
, 1, stdin
);
929 read_get_request(void)
933 if ((s
= getenv("QUERY_STRING")) == NULL
)
940 static cachemgr_request
*
941 read_request(char* buf
)
944 static cachemgr_request
*
949 cachemgr_request
*req
;
954 if ((buf
= read_post_request()) != NULL
)
956 else if ((buf
= read_get_request()) != NULL
)
963 if (strlen(buf
) == 0 || strlen(buf
) == 4000)
966 if (strlen(buf
) == 0)
971 req
= (cachemgr_request
*)xcalloc(1, sizeof(cachemgr_request
));
973 for (s
= strtok(buf
, "&"); s
!= NULL
; s
= strtok(NULL
, "&")) {
976 if ((q
= strchr(t
, '=')) == NULL
)
985 if (0 == strcasecmp(t
, "server") && strlen(q
))
986 req
->server
= xstrdup(q
);
987 else if (0 == strcasecmp(t
, "host") && strlen(q
))
988 req
->hostname
= xstrdup(q
);
989 else if (0 == strcasecmp(t
, "port") && strlen(q
))
991 else if (0 == strcasecmp(t
, "user_name") && strlen(q
))
992 req
->user_name
= xstrdup(q
);
993 else if (0 == strcasecmp(t
, "passwd") && strlen(q
))
994 req
->passwd
= xstrdup(q
);
995 else if (0 == strcasecmp(t
, "auth") && strlen(q
))
996 req
->pub_auth
= xstrdup(q
), decode_pub_auth(req
);
997 else if (0 == strcasecmp(t
, "operation"))
998 req
->action
= xstrdup(q
);
1001 if (req
->server
&& !req
->hostname
) {
1003 req
->hostname
= strtok(req
->server
, ":");
1005 if ((p
= strtok(NULL
, ":")))
1006 req
->port
= atoi(p
);
1010 debug(1) fprintf(stderr
, "cmgr: got req: host: '%s' port: %d uname: '%s' passwd: '%s' auth: '%s' oper: '%s'\n",
1011 safe_str(req
->hostname
), req
->port
, safe_str(req
->user_name
), safe_str(req
->passwd
), safe_str(req
->pub_auth
), safe_str(req
->action
));
1016 /* Routines to support authentication */
1019 * Encodes auth info into a "public" form.
1020 * Currently no powerful encryption is used.
1023 make_pub_auth(cachemgr_request
* req
) {
1024 static char buf
[1024];
1025 safe_free(req
->pub_auth
);
1026 debug(3) fprintf(stderr
, "cmgr: encoding for pub...\n");
1028 if (!req
->passwd
|| !strlen(req
->passwd
))
1031 /* host | time | user | passwd */
1032 snprintf(buf
, sizeof(buf
), "%s|%d|%s|%s",
1035 req
->user_name
? req
->user_name
: "",
1038 debug(3) fprintf(stderr
, "cmgr: pre-encoded for pub: %s\n", buf
);
1040 debug(3) fprintf(stderr
, "cmgr: encoded: '%s'\n", base64_encode(buf
));
1042 req
->pub_auth
= xstrdup(base64_encode(buf
));
1046 decode_pub_auth(cachemgr_request
* req
) {
1048 const char *host_name
;
1049 const char *time_str
;
1050 const char *user_name
;
1053 debug(2) fprintf(stderr
, "cmgr: decoding pub: '%s'\n", safe_str(req
->pub_auth
));
1054 safe_free(req
->passwd
);
1056 if (!req
->pub_auth
|| strlen(req
->pub_auth
) < 4 + strlen(safe_str(req
->hostname
)))
1059 buf
= xstrdup(base64_decode(req
->pub_auth
));
1061 debug(3) fprintf(stderr
, "cmgr: length ok\n");
1063 /* parse ( a lot of memory leaks, but that is cachemgr style :) */
1064 if ((host_name
= strtok(buf
, "|")) == NULL
)
1067 debug(3) fprintf(stderr
, "cmgr: decoded host: '%s'\n", host_name
);
1069 if ((time_str
= strtok(NULL
, "|")) == NULL
)
1072 debug(3) fprintf(stderr
, "cmgr: decoded time: '%s' (now: %d)\n", time_str
, (int) now
);
1074 if ((user_name
= strtok(NULL
, "|")) == NULL
)
1077 debug(3) fprintf(stderr
, "cmgr: decoded uname: '%s'\n", user_name
);
1079 if ((passwd
= strtok(NULL
, "|")) == NULL
)
1082 debug(2) fprintf(stderr
, "cmgr: decoded passwd: '%s'\n", passwd
);
1084 /* verify freshness and validity */
1085 if (atoi(time_str
) + passwd_ttl
< now
)
1088 if (strcasecmp(host_name
, req
->hostname
))
1091 debug(1) fprintf(stderr
, "cmgr: verified auth. info.\n");
1094 xfree(req
->user_name
);
1096 req
->user_name
= xstrdup(user_name
);
1098 req
->passwd
= xstrdup(passwd
);
1104 reset_auth(cachemgr_request
* req
) {
1105 safe_free(req
->passwd
);
1106 safe_free(req
->pub_auth
);
1110 make_auth_header(const cachemgr_request
* req
) {
1111 static char buf
[1024];
1112 size_t stringLength
= 0;
1118 snprintf(buf
, sizeof(buf
), "%s:%s",
1119 req
->user_name
? req
->user_name
: "",
1122 str64
= base64_encode(buf
);
1124 stringLength
+= snprintf(buf
, sizeof(buf
), "Authorization: Basic %s\r\n", str64
);
1126 assert(stringLength
< sizeof(buf
));
1128 stringLength
+= snprintf(&buf
[stringLength
], sizeof(buf
) - stringLength
,
1129 "Proxy-Authorization: Basic %s\r\n", str64
);
1135 check_target_acl(const char *hostname
, int port
) {
1136 char config_line
[BUFSIZ
];
1139 fp
= fopen("cachemgr.conf", "r");
1142 fp
= fopen(DEFAULT_CACHEMGR_CONFIG
, "r");
1145 #ifdef CACHEMGR_HOSTNAME_DEFINED
1147 if (strcmp(hostname
, CACHEMGR_HOSTNAME
) == 0 && port
== CACHE_HTTP_PORT
)
1152 if (strcmp(hostname
, "localhost") == 0)
1155 if (strcmp(hostname
, getfullhostname()) == 0)
1163 while (fgets(config_line
, BUFSIZ
, fp
)) {
1165 strtok(config_line
, " \r\n\t");
1167 if (config_line
[0] == '#')
1170 if (config_line
[0] == '\0')
1173 if ((token
= strtok(config_line
, ":")) == NULL
)
1178 if (fnmatch(token
, hostname
, 0) != 0)
1183 if (strcmp(token
, hostname
) != 0)
1188 if ((token
= strtok(NULL
, ":")) != NULL
) {
1191 if (strcmp(token
, "*") == 0)
1193 ; /* Wildcard port specification */
1194 else if (strcasecmp(token
, "any") == 0)
1196 ; /* Wildcard port specification */
1197 else if (sscanf(token
, "%d", &i
) != 1)
1202 } else if (port
!= CACHE_HTTP_PORT
)