📄 cachemgr.c
字号:
/* * $Id: cachemgr.c,v 1.84.2.2 1999/02/12 19:38:23 wessels Exp $ * * DEBUG: section 0 CGI Cache Manager * AUTHOR: Duane Wessels * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please see * the CREDITS file for full details. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "config.h"#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STDIO_H#include <stdio.h>#endif#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if HAVE_CTYPE_H#include <ctype.h>#endif#if HAVE_ERRNO_H#include <errno.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#if HAVE_GRP_H#include <grp.h>#endif#if HAVE_GNUMALLOC_H#include <gnumalloc.h>#elif HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)#include <malloc.h>#endif#if HAVE_MEMORY_H#include <memory.h>#endif#if HAVE_NETDB_H && !defined(_SQUID_NETDB_H_) /* protect NEXTSTEP */#define _SQUID_NETDB_H_#include <netdb.h>#endif#if HAVE_PWD_H#include <pwd.h>#endif#if HAVE_SIGNAL_H#include <signal.h>#endif#if HAVE_TIME_H#include <time.h>#endif#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if HAVE_SYS_TIME_H#include <sys/time.h>#endif#if HAVE_SYS_RESOURCE_H#include <sys/resource.h> /* needs sys/time.h above it */#endif#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_SYS_STAT_H#include <sys/stat.h>#endif#if HAVE_SYS_UN_H#include <sys/un.h>#endif#if HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#if HAVE_LIBC_H#include <libc.h>#endif#if HAVE_STRING_H#include <string.h>#endif#if HAVE_STRINGS_H#include <strings.h>#endif#if HAVE_BSTRING_H#include <bstring.h>#endif#if HAVE_CRYPT_H#include <crypt.h>#endif#if HAVE_SYS_SELECT_H#include <sys/select.h>#endif#include "util.h"#include "snprintf.h"typedef struct { char *hostname; int port; char *action; char *user_name; char *passwd; char *pub_auth;} cachemgr_request;/* * Debugging macros (info goes to error_log on your web server) * Note: do not run cache manager with non zero debugging level * if you do not debug, it may write a lot of [sensitive] * information to your error log. *//* debugging level 0 (disabled) - 3 (max) */#define DEBUG_LEVEL 0#define debug(level) if ((level) <= DEBUG_LEVEL && DEBUG_LEVEL > 0)/* * Static variables and constants */static const time_t passwd_ttl = 60 * 60 * 3; /* in sec */static const char *script_name = "/cgi-bin/cachemgr.cgi";static const char *progname = NULL;static time_t now;static struct in_addr no_addr;/* * Function prototypes */#define safe_free(str) { if (str) { xfree(str); (str) = NULL; } }static const char *safe_str(const char *str);static char *xstrtok(char **str, char del);static void print_trailer(void);static void auth_html(char *host, int port, const char *user_name);static void error_html(const char *msg);static char *menu_url(cachemgr_request * req, const char *action);static int parse_status_line(const char *sline, const char **statusStr);static cachemgr_request *read_request(void);static char *read_get_request(void);static char *read_post_request(void);static void make_pub_auth(cachemgr_request * req);static void decode_pub_auth(cachemgr_request * req);static void reset_auth(cachemgr_request * req);static const char *make_auth_header(const cachemgr_request * req);static const char *safe_str(const char *str){ return str ? str : "";}/* relaxed number format */static intis_number(const char *str){ return strspn(str, "\t -+01234567890./\n") == strlen(str);}static char *xstrtok(char **str, char del){ if (*str) { char *p = strchr(*str, del); char *tok = *str; int len; if (p) { *str = p + 1; *p = '\0'; } else *str = NULL; /* trim */ len = strlen(tok); while (len && xisspace(tok[len - 1])) tok[--len] = '\0'; while (xisspace(*tok)) tok++; return tok; } else return "";}static voidprint_trailer(void){ printf("<HR>\n"); printf("<ADDRESS>\n"); printf("Generated %s, by %s/%s@%s\n", mkrfc1123(now), progname, SQUID_VERSION, getfullhostname()); printf("</ADDRESS></BODY></HTML>\n");}static voidauth_html(char *host, int port, const char *user_name){ if (!user_name) user_name = ""; if (!host || !strlen(host)) host = "localhost"; printf("Content-type: text/html\r\n\r\n"); printf("<HTML><HEAD><TITLE>Cache Manager Interface</TITLE></HEAD>\n"); printf("<BODY><H1>Cache Manager Interface</H1>\n"); printf("<P>This is a WWW interface to the instrumentation interface\n"); printf("for the Squid object cache.</P>\n"); printf("<HR>\n"); printf("<FORM METHOD=\"GET\" ACTION=\"%s\">\n", script_name); printf("<TABLE BORDER=0>\n"); printf("<TR><TH ALIGN=\"left\">Cache Host:</TH><TD><INPUT NAME=\"host\" "); printf("SIZE=30 VALUE=\"%s\"></TD></TR>\n", host); printf("<TR><TH ALIGN=\"left\">Cache Port:</TH><TD><INPUT NAME=\"port\" "); printf("SIZE=30 VALUE=\"%d\"></TD></TR>\n", port); printf("<TR><TH ALIGN=\"left\">Manager name:</TH><TD><INPUT NAME=\"user_name\" "); printf("SIZE=30 VALUE=\"%s\"></TD></TR>\n", user_name); printf("<TR><TH ALIGN=\"left\">Password:</TH><TD><INPUT TYPE=\"password\" NAME=\"passwd\" "); printf("SIZE=30 VALUE=\"\"></TD></TR>\n"); printf("</TABLE><BR CLEAR=\"all\">\n"); printf("<INPUT TYPE=\"submit\" VALUE=\"Continue...\">\n"); printf("</FORM>\n"); print_trailer();}static voiderror_html(const char *msg){ printf("Content-type: text/html\r\n\r\n"); printf("<HTML><HEAD><TITLE>Cache Manager Error</TITLE></HEAD>\n"); printf("<BODY><H1>Cache Manager Error</H1>\n"); printf("<P>\n%s</P>\n", msg); print_trailer();}/* returns http status extracted from status line or -1 on parsing failure */static intparse_status_line(const char *sline, const char **statusStr){ const char *sp = strchr(sline, ' '); if (statusStr) *statusStr = NULL; if (strncasecmp(sline, "HTTP/", 5) || !sp) return -1; while (xisspace(*++sp)); if (!xisdigit(*sp)) return -1; if (statusStr) *statusStr = sp; return atoi(sp);}static char *menu_url(cachemgr_request * req, const char *action){ static char url[1024]; snprintf(url, sizeof(url), "%s?host=%s&port=%d&user_name=%s&operation=%s&auth=%s", script_name, req->hostname, req->port, safe_str(req->user_name), action, safe_str(req->pub_auth)); return url;}static const char *munge_menu_line(const char *buf, cachemgr_request * req){ char *x; const char *a; const char *d; const char *p; char *a_url; char *buf_copy; static char html[2 * 1024]; if (strlen(buf) < 1) return buf; if (*buf != ' ') return buf; buf_copy = x = xstrdup(buf); a = xstrtok(&x, '\t'); d = xstrtok(&x, '\t'); p = xstrtok(&x, '\t'); a_url = xstrdup(menu_url(req, a)); /* no reason to give a url for a disabled action */ if (!strcmp(p, "disabled")) snprintf(html, sizeof(html), "<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url); else /* disable a hidden action (requires a password, but password is not in squid.conf) */ if (!strcmp(p, "hidden")) snprintf(html, sizeof(html), "<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url); else /* disable link if authentication is required and we have no password */ if (!strcmp(p, "protected") && !req->passwd) snprintf(html, sizeof(html), "<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n", d, menu_url(req, "authenticate"), a_url); else /* highlight protected but probably available entries */ if (!strcmp(p, "protected")) snprintf(html, sizeof(html), "<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n", a_url, d); /* public entry or unknown type of protection */ else snprintf(html, sizeof(html), "<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d); xfree(a_url); xfree(buf_copy); return html;}static const char *munge_other_line(const char *buf, cachemgr_request * req){ static const char *ttags[] = {"td", "th"}; static char html[4096]; static int table_line_num = 0; static int next_is_header = 0; int is_header = 0; const char *ttag; char *buf_copy; char *x, *p; int l = 0; /* does it look like a table? */ if (!strchr(buf, '\t') || *buf == '\t') { /* nope, just text */ snprintf(html, sizeof(html), "%s%s", table_line_num ? "</table>\n<pre>" : "", buf); table_line_num = 0; return html; } /* start html table */ if (!table_line_num) { l += snprintf(html + l, sizeof(html) - l, "</pre><table border=1 cellpadding=2 cellspacing=1>\n"); next_is_header = 0; } /* remove '\n' */ is_header = (!table_line_num || next_is_header) && !strchr(buf, ':') && !is_number(buf); ttag = ttags[is_header]; /* record starts */ l += snprintf(html + l, sizeof(html) - l, "<tr>");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -