Пример #1
0
static int
tunnelHandlerParent(int fd, TunnelPtr tunnel)
{
    char *message;
    int n;

    if(tunnel->buf1.buf == NULL)
        tunnel->buf1.buf = get_chunk();
    if(tunnel->buf1.buf == NULL) {
        message = "Couldn't allocate buffer";
        goto fail;
    }
    if(tunnel->buf1.tail != tunnel->buf1.head) {
        message = "Pipelined connect to parent proxy not implemented";
        goto fail;
    }

    n = snnprintf(tunnel->buf1.buf, tunnel->buf1.tail, CHUNK_SIZE,
                  "CONNECT %s:%d HTTP/1.1",
                  tunnel->hostname->string, tunnel->port);
    if (parentAuthCredentials)
        n = buildServerAuthHeaders(tunnel->buf1.buf, n, CHUNK_SIZE,
                                   parentAuthCredentials);
    n = snnprintf(tunnel->buf1.buf, n, CHUNK_SIZE, "\r\n\r\n");

    if(n < 0) {
        message = "Buffer overflow";
        goto fail;
    }
    tunnel->buf1.head = n;
    tunnelDispatch(tunnel);
    return 1;

 fail:
    CLOSE(fd);
    tunnel->fd2 = -1;
    tunnelError(tunnel, 501, internAtom(message));
    return 1;
}
Пример #2
0
int
readDomainFile(char *filename)
{
    FILE *in;
    char buf[512];
    char *rs;
    int i, j, is_regex, start;

    in = fopen(filename, "r");
    if(in == NULL) {
        if(errno != ENOENT)
            do_log_error(L_ERROR, errno, "Couldn't open file %s", filename);
        return -1;
    }

    while(1) {
        rs = fgets(buf, 512, in);
        if(rs == NULL)
            break;
        for(i = 0; i < 512; i++) {
            if(buf[i] != ' ' && buf[i] != '\t')
                break;
        }
        start = i;
        for(i = start; i < 512; i++) {
            if(buf[i] == '#' || buf[i] == '\r' || buf[i] == '\n')
                break;
        }
        while(i > start) {
            if(buf[i - 1] != ' ' && buf[i - 1] != '\t')
                break;
            i--;
        }

        if(i <= start)
            continue;

        /* The significant part of the line is now between start and i */

        is_regex = 0;
        for(j = start; j < i; j++) {
            if(buf[j] == '\\' || buf[j] == '*' || buf[j] == '/') {
                is_regex = 1;
                break;
            }
        }

        if(is_regex) {
            while(rlen + i - start + 8 >= rsize) {
                char *new_regexbuf;
                new_regexbuf = realloc(regexbuf, rsize * 2 + 1);
                if(new_regexbuf == NULL) {
                    do_log(L_ERROR, "Couldn't reallocate regex.\n");
                    fclose(in);
                    return -1;
                }
                regexbuf = new_regexbuf;
                rsize = rsize * 2 + 1;
            }
            if(rlen != 0)
                rlen = snnprintf(regexbuf, rlen, rsize, "|");
            rlen = snnprintf(regexbuf, rlen, rsize, "(");
            rlen = snnprint_n(regexbuf, rlen, rsize, buf + start, i - start);
            rlen = snnprintf(regexbuf, rlen, rsize, ")");
        } else {
            DomainPtr new_domain;
            if(dlen >= dsize - 1) {
                DomainPtr *new_domains;
                new_domains = realloc(domains, (dsize * 2 + 1) *
                                      sizeof(DomainPtr));
                if(new_domains == NULL) {
                    do_log(L_ERROR,
                           "Couldn't reallocate domain list.\n");
                    fclose(in);
                    return -1;
                }
                domains = new_domains;
                dsize = dsize * 2 + 1;
            }
            new_domain = malloc(sizeof(DomainRec) - 1 + i - start);
            if(new_domain == NULL) {
                do_log(L_ERROR, "Couldn't allocate domain.\n");
                fclose(in);
                return -1;
            }
            new_domain->length = i - start;
            memcpy(new_domain->domain, buf + start, i - start);
            domains[dlen++] = new_domain;
        }
    }
    fclose(in);
    return 1;
}
Пример #3
0
int
httpSpecialRequest(ObjectPtr object, int method, int from, int to,
		   HTTPRequestPtr requestor, void *closure)
{
	char buffer[1024];
	int hlen;

	if (method >= METHOD_POST) {
		return httpSpecialSideRequest(object, method, from, to,
					      requestor, closure);
	}

	if (!(object->flags & OBJECT_INITIAL)) {
		privatiseObject(object, 0);
		supersedeObject(object);
		object->flags &= ~(OBJECT_VALIDATING | OBJECT_INPROGRESS);
		notifyObject(object);
		return 1;
	}

	hlen = snnprintf(buffer, 0, 1024,
			 "\r\nServer: s_server" "\r\nContent-Type: text/html");
	object->date = current_time.tv_sec;
	object->age = current_time.tv_sec;
	object->headers = internAtomN(buffer, hlen);
	object->code = 200;
	object->message = internAtom("Okay");
	object->flags &= ~OBJECT_INITIAL;
	object->flags |= OBJECT_DYNAMIC;

	if (object->key_size == 8 && memcmp(object->key, "/s_server/", 8) == 0) {
		objectPrintf(object, 0,
			     "<!DOCTYPE HTML PUBLIC "
			     "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
			     "\"http://www.w3.org/TR/html4/loose.dtd\">\n"
			     "<html><head>\n"
			     "<title>Polipo</title>\n"
			     "</head><body>\n"
			     "<h1>Polipo</h1>\n"
			     "<p><a href=\"status?\">Status report</a>.</p>\n"
			     "<p><a href=\"config?\">Current configuration</a>.</p>\n"
			     "<p><a href=\"servers?\">Known servers</a>.</p>\n"
#ifndef NO_DISK_CACHE
			     "<p><a href=\"index?\">Disk cache index</a>.</p>\n"
#endif
			     "</body></html>\n");
		object->length = object->size;
	} else if (matchUrl("/s_server/status", object)) {
		objectPrintf(object, 0,
			     "<!DOCTYPE HTML PUBLIC "
			     "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
			     "\"http://www.w3.org/TR/html4/loose.dtd\">\n"
			     "<html><head>\n"
			     "<title>Polipo status report</title>\n"
			     "</head><body>\n"
			     "<h1>Polipo proxy on %s:%d: status report</h1>\n"
			     "<p>The %s proxy on %s:%d is %s.</p>\n"
			     "<p>There are %d public and %d private objects "
			     "currently in memory using %d KB in %d chunks "
			     "(%d KB allocated).</p>\n"
			     "<p>There are %d atoms.</p>"
			     "<p><form method=POST action=\"/s_server/status?\">"
			     "<input type=submit name=\"init-forbidden\" "
			     "value=\"Read forbidden file\"></form>\n"
			     "<form method=POST action=\"/s_server/status?\">"
			     "<input type=submit name=\"writeout-objects\" "
			     "value=\"Write out in-memory cache\"></form>\n"
			     "<form method=POST action=\"/s_server/status?\">"
			     "<input type=submit name=\"discard-objects\" "
			     "value=\"Discard in-memory cache\"></form>\n"
			     "<form method=POST action=\"/s_server/status?\">"
			     "<input type=submit name=\"reopen-log\" "
			     "value=\"Reopen log file\"></form>\n"
			     "<form method=POST action=\"/s_server/status?\">"
			     "<input type=submit name=\"free-chunk-arenas\" "
			     "value=\"Free chunk arenas\"></form></p>\n"
			     "<p><a href=\"/s_server/\">back</a></p>"
			     "</body></html>\n",
			     proxyName->string, proxyPort,
			     cacheIsShared ? "shared" : "private",
			     proxyName->string, proxyPort,
			     proxyOffline ? "off line" :
			     (relaxTransparency ?
			      "on line (transparency relaxed)" :
			      "on line"),
			     publicObjectCount, privateObjectCount,
			     used_chunks * CHUNK_SIZE / 1024, used_chunks,
			     totalChunkArenaSize() / 1024, used_atoms);
		object->expires = current_time.tv_sec;
		object->length = object->size;
	} else if (matchUrl("/s_server/config", object)) {
		fillSpecialObject(object, printConfig, NULL);
		object->expires = current_time.tv_sec + 5;
#ifndef NO_DISK_CACHE
	} else if (matchUrl("/s_server/index", object)) {
		int len;
		char *root;
		if (disableIndexing) {
			abortObject(object, 403,
				    internAtom("Action not allowed"));
			notifyObject(object);
			return 1;
		}
		len = MAX(0, object->key_size - 14);
		root = strdup_n((char *)object->key + 14, len);
		if (root == NULL) {
			abortObject(object, 503,
				    internAtom("Couldn't allocate root"));
			notifyObject(object);
			return 1;
		}
		writeoutObjects(1);
		fillSpecialObject(object, plainIndexDiskObjects, root);
		free(root);
		object->expires = current_time.tv_sec + 5;
	} else if (matchUrl("/s_server/recursive-index", object)) {
		int len;
		char *root;
		if (disableIndexing) {
			abortObject(object, 403,
				    internAtom("Action not allowed"));
			notifyObject(object);
			return 1;
		}
		len = MAX(0, object->key_size - 24);
		root = strdup_n((char *)object->key + 24, len);
		if (root == NULL) {
			abortObject(object, 503,
				    internAtom("Couldn't allocate root"));
			notifyObject(object);
			return 1;
		}
		writeoutObjects(1);
		fillSpecialObject(object, recursiveIndexDiskObjects, root);
		free(root);
		object->expires = current_time.tv_sec + 20;
#endif
	} else if (matchUrl("/s_server/servers", object)) {
		if (disableServersList) {
			abortObject(object, 403,
				    internAtom("Action not allowed"));
			notifyObject(object);
			return 1;
		}
		fillSpecialObject(object, serversList, NULL);
		object->expires = current_time.tv_sec + 2;
	} else {
		abortObject(object, 404, internAtom("Not found"));
	}

	object->flags &= ~OBJECT_VALIDATING;
	notifyObject(object);
	return 1;
}