Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
static const char *
munge_action_line(const char *_buf, cachemgr_request * req)
{
    static char html[2 * 1024];
    char *buf = xstrdup(_buf);
    char *x = buf;
    const char *action, *description;
    char *p;

    if ((p = strchr(x, '\n')))
	*p = '\0';
    action = xstrtok(&x, '\t');
    description = xstrtok(&x, '\t');
    if (!description)
	description = action;
    if (!action)
	return "";
    snprintf(html, sizeof(html), " <a href=\"%s\">%s</a>", menu_url(req, action), description);
    return html;
}
Ejemplo n.º 3
0
static int
read_reply(int s, cachemgr_request * req)
{
    char buf[4 * 1024];
    FILE *fp = fdopen(s, "r");
    /* interpretation states */
    enum {
	isStatusLine, isHeaders, isBodyStart, isBody, isForward, isEof, isForwardEof, isSuccess, isError
    } istate = isStatusLine;
    int parse_menu = 0;
    const char *action = req->action;
    const char *statusStr = NULL;
    int status = -1;
    if (0 == strlen(req->action))
	parse_menu = 1;
    else if (0 == strcasecmp(req->action, "menu"))
	parse_menu = 1;
    if (fp == NULL) {
	perror("fdopen");
	return 1;
    }
    if (parse_menu)
	action = "menu";
    /* read reply interpreting one line at a time depending on state */
    while (istate < isEof) {
	if (!fgets(buf, sizeof(buf), fp))
	    istate = istate == isForward ? isForwardEof : isEof;
	switch (istate) {
	case isStatusLine:
	    /* get HTTP status */
	    /* uncomment the following if you want to debug headers */
	    /* fputs("\r\n\r\n", stdout); */
	    status = parse_status_line(buf, &statusStr);
	    istate = status == 200 ? isHeaders : isForward;
	    /* if cache asks for authentication, we have to reset our info */
	    if (status == 401 || status == 407) {
		reset_auth(req);
		status = 403;	/* Forbiden, see comments in case isForward: */
	    }
	    /* this is a way to pass HTTP status to the Web server */
	    if (statusStr)
		printf("Status: %d %s", status, statusStr);	/* statusStr has '\n' */
	    break;
	case isHeaders:
	    /* forward header field */
	    if (!strcmp(buf, "\r\n")) {		/* end of headers */
		fputs("Content-Type: text/html\r\n", stdout);	/* add our type */
		istate = isBodyStart;
	    }
	    if (strncasecmp(buf, "Content-Type:", 13))	/* filter out their type */
		fputs(buf, stdout);
	    break;
	case isBodyStart:
	    printf("<HTML><HEAD><TITLE>CacheMgr@%s: %s</TITLE></HEAD><BODY>\n",
		req->hostname, action);
	    if (parse_menu) {
		printf("<H2><a href=\"%s\">Cache Manager</a> menu for %s:</H2>",
		    menu_url(req, "authenticate"), req->hostname);
		printf("<UL>\n");
	    } else {
		printf("<P><A HREF=\"%s\">%s</A>\n<HR>\n",
		    menu_url(req, "menu"), "Cache Manager menu");
		printf("<PRE>\n");
	    }
	    istate = isBody;
	    /* yes, fall through, we do not want to loose the first line */
	case isBody:
	    /* interpret [and reformat] cache response */
	    if (parse_menu)
		fputs(munge_menu_line(buf, req), stdout);
	    else
		fputs(munge_other_line(buf, req), stdout);
	    break;
	case isForward:
	    /* forward: no modifications allowed */
	    /*
	     * Note: we currently do not know any way to get browser.reply to
	     * 401 to .cgi because web server filters out all auth info. Thus we
	     * disable authentication headers for now.
	     */
	    if (!strncasecmp(buf, "WWW-Authenticate:", 17) || !strncasecmp(buf, "Proxy-Authenticate:", 19));	/* skip */
	    else
		fputs(buf, stdout);
	    break;
	case isEof:
	    /* print trailers */
	    if (parse_menu)
		printf("</UL>\n");
	    else
		printf("</table></PRE>\n");
	    print_trailer();
	    istate = isSuccess;
	    break;
	case isForwardEof:
	    /* indicate that we finished processing an "error" sequence */
	    istate = isError;
	    break;
	default:
	    printf("%s: internal bug: invalid state reached: %d", script_name, istate);
	    istate = isError;
	}
    }
    close(s);
    return 0;
}
Ejemplo n.º 4
0
static int
read_reply(int s, cachemgr_request * req)
{
    char buf[4 * 1024];
#ifdef _SQUID_MSWIN_
    int reply;
    char *tmpfile = tempnam(NULL, "tmp0000");
    FILE *fp = fopen(tmpfile, "w+");
#else
    FILE *fp = fdopen(s, "r");
#endif
    /* interpretation states */
    enum {
	isStatusLine, isHeaders, isActions, isBodyStart, isBody, isForward, isEof, isForwardEof, isSuccess, isError
    } istate = isStatusLine;
    int parse_menu = 0;
    const char *action = req->action;
    const char *statusStr = NULL;
    int status = -1;
    if (0 == strlen(req->action))
	parse_menu = 1;
    else if (0 == strcasecmp(req->action, "menu"))
	parse_menu = 1;
    if (fp == NULL) {
#ifdef _SQUID_MSWIN_
	perror(tmpfile);
	xfree(tmpfile);
	closesocket(s);
#else
	perror("fdopen");
	close(s);
#endif
	return 1;
    }
#ifdef _SQUID_MSWIN_
    while ((reply = recv(s, buf, sizeof(buf), 0)) > 0)
	fwrite(buf, 1, reply, fp);
    rewind(fp);
#endif
    if (parse_menu)
	action = "menu";
    /* read reply interpreting one line at a time depending on state */
    while (istate < isEof) {
	if (!fgets(buf, sizeof(buf), fp))
	    istate = istate == isForward ? isForwardEof : isEof;
	switch (istate) {
	case isStatusLine:
	    /* get HTTP status */
	    /* uncomment the following if you want to debug headers */
	    /* fputs("\r\n\r\n", stdout); */
	    status = parse_status_line(buf, &statusStr);
	    istate = status == 200 ? isHeaders : isForward;
	    /* if cache asks for authentication, we have to reset our info */
	    if (status == 401 || status == 407) {
		reset_auth(req);
		status = 403;	/* Forbiden, see comments in case isForward: */
	    }
	    /* this is a way to pass HTTP status to the Web server */
	    if (statusStr)
		printf("Status: %d %s", status, statusStr);	/* statusStr has '\n' */
	    break;
	case isHeaders:
	    /* forward header field */
	    if (!strcmp(buf, "\r\n")) {		/* end of headers */
		fputs("Content-Type: text/html\r\n", stdout);	/* add our type */
		istate = isBodyStart;
	    }
	    if (strncasecmp(buf, "Content-Type:", 13))	/* filter out their type */
		fputs(buf, stdout);
	    break;
	case isBodyStart:
	    printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
	    printf("<HTML><HEAD><TITLE>CacheMgr@%s: %s</TITLE>\n",
		req->hostname, action);
	    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");
	    printf("</HEAD><BODY>\n");
	    if (parse_menu) {
		printf("<H2><a href=\"%s\">Cache Manager</a> menu for %s:</H2>",
		    menu_url(req, "authenticate"), req->hostname);
	    } else {
		printf("<P><A HREF=\"%s\">%s</A>\n",
		    menu_url(req, "menu"), "Cache Manager menu");
	    }
	    istate = isActions;
	    /* yes, fall through, we do not want to loose the first line */
	case isActions:
	    if (strncmp(buf, "action:", 7) == 0) {
		fputs(" ", stdout);
		fputs(munge_action_line(buf + 7, req), stdout);
		break;
	    }
	    if (parse_menu) {
		printf("<UL>\n");
	    } else {
		printf("<HR noshade size=\"1px\">\n");
		printf("<PRE>\n");
	    }
	    istate = isBody;
	    /* yes, fall through, we do not want to loose the first line */
	case isBody:
	    /* interpret [and reformat] cache response */
	    if (parse_menu)
		fputs(munge_menu_line(buf, req), stdout);
	    else
		fputs(munge_other_line(buf, req), stdout);
	    break;
	case isForward:
	    /* forward: no modifications allowed */
	    /*
	     * Note: we currently do not know any way to get browser.reply to
	     * 401 to .cgi because web server filters out all auth info. Thus we
	     * disable authentication headers for now.
	     */
	    if (!strncasecmp(buf, "WWW-Authenticate:", 17) || !strncasecmp(buf, "Proxy-Authenticate:", 19));	/* skip */
	    else
		fputs(buf, stdout);
	    break;
	case isEof:
	    /* print trailers */
	    if (parse_menu)
		printf("</UL>\n");
	    else
		printf("</table></PRE>\n");
	    print_trailer();
	    istate = isSuccess;
	    break;
	case isForwardEof:
	    /* indicate that we finished processing an "error" sequence */
	    istate = isError;
	    break;
	default:
	    printf("%s: internal bug: invalid state reached: %d", script_name, istate);
	    istate = isError;
	}
    }
#ifdef _SQUID_MSWIN_
    fclose(fp);
    remove(tmpfile);
    xfree(tmpfile);
    closesocket(s);
#else
    close(s);
#endif
    return 0;
}