Esempio n. 1
0
static void io_write(char* filename,int fd)
{
	char path[100] = "html/";
	strcat(path,filename);
	char buf[1024];
	printf(path);
	printf("\n");
	int file = open((char*)path,O_RDONLY);
	if(file == -1)
	{
		http_header(fd,-1);
		int c = sprintf(buf,"cannot find this file in the server,please check again!\n");
		send(fd,buf,c,0);
		printf("hello \n");
		return ;
	}
//	printf("end of not find\n");
	http_header(fd,1);
	int count = read(file,buf,sizeof buf);
	
	while(count != 0)
	{
		write(fd,buf,count);
		count = read(file,buf,sizeof buf);
	}
	write(fd,"\0",1);

	close(file);
}
Esempio n. 2
0
void
connection_base::print_common_headers(std::string const &content_type, std::streambuf &buf) const {

	std::ostream stream(&buf);

	stream << http_date(boost::posix_time::second_clock::universal_time());
	stream << http_header::server();
	stream << http_header("Content-Type", content_type.c_str());

	if (headers_ && !headers_->empty()) {
		response_impl::headers_data_type::const_iterator it = headers_->begin(), end = headers_->end();
		for (; it != end; ++it) {
			stream << http_header(it->first.c_str(), it->second.c_str());
		}
	}
}
Esempio n. 3
0
uint http_send_ok(uchar nr, char *html_page, int nStatus, char *szTitle)
{
	char	*pbuf;
	char	html_buf[MAX_ETHER_PKT_LEN];
	uint	page_len = 0;
	uint 	hdr_len;
	uint 	body_len;

	/* fill html title to html buffer */
	page_len += sprintf(&html_buf[page_len], 
			"<html><head><title>%s</title></head>", _HTTP_TITLE);
	/* copy html body to html buffer */
	memcpy(&html_buf[page_len], html_page, strlen(html_page));
	page_len += strlen(html_page);
	
	/* fill html header to packet buffer */
	pbuf = http_buf + 54;
	hdr_len = http_header(pbuf, nStatus, szTitle, page_len);
	
	/* copy html buffer to packet buffer */
	memcpy(&pbuf[hdr_len],html_buf,page_len);
	
	body_len = hdr_len + page_len;
	
	pbuf[54 + body_len] = 0;	/* Append NULL */

	/* Segment length = body_len + 20(TCP header) */
	http_send((uchar *)http_buf, body_len + 20, nr);
	conxn[nr].my_sequence += body_len;
	
	return 0;	
}
Esempio n. 4
0
uint http_send_error(uchar nr, int nStatus, char *szTitle, char *szText)
{
	char	*pbuf;
	char	html_buf[MAX_ETHER_PKT_LEN];
	uint	page_len = 0;
	uint 	hdr_len;
	uint 	body_len;
	
	page_len += sprintf(&html_buf[page_len], 
			"<html><head><title>%s</title></head>", _HTTP_TITLE);
	page_len += sprintf(&html_buf[page_len],
			"<body>%s</body></html>", szText);
			
	pbuf = http_buf + 54;
	hdr_len = http_header(pbuf, nStatus, szTitle, page_len);
	memcpy(&pbuf[hdr_len],html_buf,page_len);
	
	body_len = hdr_len + page_len;
	
	pbuf[54 + body_len] = 0;	/* Append NULL */

	/* Segment length = body_len + 20(TCP header) */
	http_send((uchar *)http_buf, body_len + 20, nr);
	conxn[nr].my_sequence += body_len;
	
	return 0;
}
Esempio n. 5
0
HttpServletResponse::HttpServletResponse(socket_stream& stream)
    : stream_(stream)
{
    header_ = NEW http_header();
    header_->set_request_mode(false);
    charset_[0] = 0;
    snprintf(content_type_, sizeof(content_type_), "text/html");
}
Esempio n. 6
0
int main(int argc, char *argv[])
{
   char header[] = "Powered-by: ANSI C scripts\r\n";
   http_header(HEAD_ADD, header, sizeof(header) - 1, argv);
   
   xbuf_cat(get_reply(argv), "Look at the HTTP headers");

   return 200; // return an HTTP code (200:'OK')
}
Esempio n. 7
0
File: http.c Progetto: ghuntley/axel
long long int http_size( http_t *conn )
{
    char *i;
    long long int j;

    if( ( i = http_header( conn, "Content-Length:" ) ) == NULL )
        return( -2 );

    sscanf( i, "%lld", &j );
    return( j );
}
Esempio n. 8
0
bool
connection_base::print_error(std::streambuf &buf, http_error const &http) const {

	std::ostream stream(&buf);
	stream << http_status(http.code());
	stream << http_date(boost::posix_time::second_clock::universal_time());
	stream << http_header::server();
	stream << http_header::connection_close();
	stream << http_header("Content-Type", "text/plain; charset=utf-8");
	stream << http_constants<char>::endl;
	return true;
}
Esempio n. 9
0
static int login_screen(void)
{
	http_header();
	const char *ref = get_login_referer();
	printf("<meta http-equiv='Content-Type' content='text/html; charset=gb2312' />"
			"<link rel='stylesheet' type='text/css' href='/css/bbs.css' />"
			"<title>Óû§µÇ¼ - "BBSNAME"</title></head>"
			"<body><form action='login' method='post'>"
			"<label for='id'>ÕʺÅ</label><input type='text' name='id' /><br />"
			"<label for='pw'>ÃÜÂë</label><input type='password' name='pw' /><br />"
			"<input type='hidden' name='ref' value='%s'/>"
			"<input type='submit' value='怬' />"
			"</form></body></html>", ref);
	return 0;
}
Esempio n. 10
0
//GET&HEAD Response handler 
void http_GETHEAD_response(char* writebuf, int writebuf_size, HTTPResponse* response)
{
 FILE *resource = NULL;
 
 resource = fopen(response->path, "r");
 if (resource == NULL)
  http_not_found(writebuf, writebuf_size, response);
 else
 {
  http_header(writebuf, writebuf_size, resource, response);
  if(!strcasecmp(response->method, "GET"))
   http_content(writebuf, writebuf_size, response);
 }

}
/**
 * Supplies blocks of data to server_current_tcp_out.
 */
static void server_tcp_out(struct tcp_pcb *pcb, struct server_tcp_state *ss) {
  if (ss->connected) { /* If we're connected */
    if (server_current_tcp_out(pcb, ss)) { /* If the current block is empty */
      /* Clear our position */
      ss->current_pos = 0;
      ss->current_len = 0;
      /* Select a new data block to output */
      switch(ss->output_phase) {
	case OP_HTTP_HEADER: /* Send a header that specifies how many records we are going to send */
	  ss->current_len = http_header(ss->output_buffer, ss->auth, ss->records_count);
	  ss->output_phase++;
	  break;
	case OP_JSON_HEADER: /* Start the JSON object */
	  ss->current_len = json_header(ss->output_buffer);
	  ss->output_phase++;
	  break;
	case OP_JSON_DATA:
	  if (ss->records_index++ < ss->records_count) { /* If there are more records to be output */
	    /* Read from memory, and encode as a JSON element */
	    ss->current_len = json_element(ss->output_buffer,
					   get_sample(ss->mem_output_index++), /* Read in the data from memory */
					   (ss->records_index < ss->records_count)); /* If this isn't the last, we need a comma */
	  } else { ss->output_phase++; }
	  break;
	case OP_JSON_FOOTER: /* End the JSON object */
	  ss->current_len = json_footer(ss->output_buffer);
	  ss->output_phase++;
	  break;
	case OP_WAIT_BEFORE_CLOSE: /* Wait before closing the connection */
	  if (ss->wait_before_close_counter++ > WAIT_BEFORE_CLOSE) {
	    ss->output_phase++;
	  }
	  break;
	case OP_CLOSE:
	  tcp_close(ss->pcb); /* Close the connection */
	  ss->output_phase++;
	  break;
      }

      /* And output that */
      server_current_tcp_out(pcb, ss);
    }
  }
}
Esempio n. 12
0
int bbsclear_main(void)
{
	if (!loginok)
		return BBS_ELGNREQ;
	const char *board = getparm("board");
	struct boardheader *bp = getbcache(board);
	if (bp == NULL || !hasreadperm(&currentuser, bp))
		return BBS_ENOBRD;
	const char *start = getparm("start");
	brc_fcgi_init(currentuser.userid, board);
	brc_clear(NA, NULL, YEA);
	brc_update(currentuser.userid, board);
	char buf[STRLEN];
	snprintf(buf, sizeof(buf), "doc?board=%s&start=%s", board, start);
	http_header();
	refreshto(0, buf);
	printf("</head></html>");
	return 0;
}
Esempio n. 13
0
static response *resolve_stream(const char *url)
{
    request *request = http_get(url);
    response *response = http_send(request);

    if (http_read_body(response) < 0 && response->status != 302) {
        fprintf(stderr, "request failed %s", url); 
        return NULL;
    }

    sds stream_url = sdsnew(http_header(response, "Location"));

    free_response(response);

    request = http_get(stream_url);
    response = http_send(request);
    
    sdsfree(stream_url);

    return response;
}
Esempio n. 14
0
bool
connection_base::print_headers(std::string const &content_type, std::streambuf &buf) const {

	bool is_websocket = !ws_info_.empty();
	if (is_websocket && !ws_info_.valid()) {
		return false;
	}

	std::ostream stream(&buf);
	if (is_websocket) {
		ws_info_.write_headers(stream);
	}
	else {
		stream << http_status(200);
		stream << http_header::connection_close();
		stream << http_header("Transfer-Encoding", "chunked");
	}
	print_common_headers(content_type, buf);
	stream << http_constants<char>::endl;
	if (is_websocket) {
		ws_info_.write_body(stream);
	}
	return true;
}
Esempio n. 15
0
bool WTOAuthConnection::gen_sigbase_and_auth(const char *req_type, const void *data)
{
	char *base_uri; size_t uri_length; char *stripped_uri; size_t stripped_len;
	WTDictionary *param_dict; WTSizedBuffer *params; char *next_param; char *enc_params;
	char nonce[8], *timestamp; size_t timestamp_len;
	char *encoded_uri; size_t sig_base_len;
	char *key; unsigned char *signature; size_t key_len; unsigned int signature_len;
	char *b64_sig;  size_t b64_sig_len = 28; char *enc_b64_sig;
	char *auth_header; size_t auth_header_len;
	
	//
	// Ensure we are needed/wanted
	if(consumer_key == NULL && token == NULL) return false;
	
	
	// 
	// Calculate the length of the URI string
	stripped_uri = strchr(uri, static_cast<int>('?'));
	if(stripped_uri != NULL)
	{
		stripped_len = abs(uri - stripped_uri);
		stripped_uri = static_cast<char *>(calloc(stripped_len + 1, sizeof(char)));
		strncpy(stripped_uri, uri, stripped_len);
		stripped_uri[stripped_len] = '\0';
	} else {
		stripped_uri = strdup(uri);
		stripped_len = strlen(uri);
	}
	
	uri_length  = strlen(protocol) + 3 + strlen(domain); // 3 is for "://"
	uri_length += stripped_len;	// add the URI
	uri_length++;			// add NUL byte
	
	
	
	// 
	// Create the Base String URI
	base_uri = static_cast<char *>(calloc(uri_length, sizeof(char)));
	if(base_uri == NULL) alloc_error("OAuth base string URI buffer", uri_length);
	snprintf(base_uri, uri_length, "%s://%s%s", protocol, domain, stripped_uri);
	
	
	
	// 
	// Generate nonce and timestamp
	timestamp_len = snprintf(NULL, 0, "%ld", time(NULL)) + 1;
	timestamp = static_cast<char *>(calloc(timestamp_len, sizeof(char)));
	if(timestamp == NULL) alloc_error("OAuth timestamp buffer", timestamp_len);
	snprintf(timestamp, timestamp_len, "%ld", time(NULL));
	
	srand(time(NULL));
	snprintf(nonce, sizeof(nonce), "%02x%02x%02x%02x",
		 rand() % 128, rand() % 128, rand() % 128, rand() % 128);
	
	
	
	// 
	// Parameters
	param_dict = new WTDictionary;
	
	next_param = (this->query_string == NULL ? NULL : this->query_string+1);
	
	while (next_param != NULL)
	{
		char *name, *value;
		
		value = strchr(next_param, static_cast<int>('='));
		if(value != NULL)
		{
			value[0] = '\0';	// Replace = with \0 for name
			value++;
		}
		
		name = next_param;
		
		next_param = strchr(value, static_cast<int>('&'));
		if(next_param != NULL)
		{
			next_param[0] = '\0';	// Terminate the value (or name)
			next_param++;
		}
		
		param_dict->set(name, (value == NULL ? strdup("") : strdup(value)));
		if(value != NULL) value[-1] = '=';
		if(next_param != NULL) next_param[-1] = '&';
	}
	
	if(consumer_key != NULL)
		param_dict->set("oauth_consumer_key", strdup(consumer_key));
	if(token != NULL)
		param_dict->set("oauth_token", strdup(token));
	
	param_dict->set("oauth_nonce", strdup(nonce));
	param_dict->set("oauth_signature_method", strdup(sigmeth_enum_to_str(sig_method)));
	param_dict->set("oauth_timestamp", strdup(timestamp));
	param_dict->set("oauth_version", strdup("1.0"));
	
	params = param_dict->all("%s=%s&");
	
	
	
	// 
	// Signature Base String generation
	params->buffer[params->buffer_len - 2] = '\0';	// remove trailing &
	encoded_uri = URLEncode(base_uri);
	enc_params = URLEncode(params->buffer);
	free(params->buffer);
	free(params);
	params = NULL;
	sig_base_len = snprintf(NULL, 0, "%s&%s&%s",
				req_type, encoded_uri, enc_params);
	sig_base_len++;
	sig_base = static_cast<char *>(calloc(sig_base_len, sizeof(char)));
	if(sig_base == NULL) alloc_error("OAuth signature base string buffer", sig_base_len);
	snprintf(sig_base, sig_base_len, "%s&%s&%s",
		 req_type, encoded_uri, enc_params);
	//fprintf(stderr, "OAUTH DEBUG: Signature base string is %s\n", sig_base);
	//fflush(stderr);
	
	
	// 
	// Generate the real signature now.
	key_len = snprintf(NULL, 0, "%s&%s", (consumer_secret == NULL ? "" : consumer_secret), (token_secret == NULL ? "" : token_secret));
	key_len++;
	key = static_cast<char *>(calloc(key_len, sizeof(char)));
	if(key == NULL) alloc_error("OAuth private key", key_len);
	snprintf(key, key_len, "%s&%s", (consumer_secret == NULL ? "" : consumer_secret), (token_secret == NULL ? "" : token_secret));
	signature = static_cast<unsigned char *>(calloc(EVP_MAX_MD_SIZE, sizeof(char)));
	if(signature == NULL) alloc_error("OAuth HMAC signature buffer", EVP_MAX_MD_SIZE);
	HMAC(EVP_sha1(), static_cast<const void *>(const_cast<const char *>(key)), key_len - 1, reinterpret_cast<const unsigned char *>(const_cast<const char *>(sig_base)), sig_base_len - 1, signature, &signature_len);
	
	
	
	// 
	// base64-encode it!  I love OAuth!
	// You think this is bad?  Wait til you see the auth header code below.
	b64_sig = static_cast<char *>(calloc(b64_sig_len, sizeof(char)));
	if(b64_sig == NULL) alloc_error("base64 buffer", b64_sig_len);
	base64::encoder b64encoder;
	b64_sig_len = b64encoder.encode(reinterpret_cast<const char *>(signature), signature_len, b64_sig);
	b64encoder.encode_end(b64_sig + b64_sig_len);
	
	
	
	// 
	// Authorization[sic.] header
	enc_b64_sig = URLEncode(b64_sig);
	free(b64_sig);
	auth_header_len = snprintf(NULL, 0, "OAuth Realm=\"\",%s%s%s oauth_nonce=\"%s\", oauth_signature_method=\"%s\", oauth_timestamp=\"%s\",%s%s%s oauth_version=\"1.0\", oauth_signature=\"%s\"",
				   (consumer_key == NULL ? "" : " oauth_consumer_key=\""), (consumer_key == NULL ? "" : consumer_key), (consumer_key == NULL ? "" : "\","),
				   nonce, sigmeth_enum_to_str(sig_method), timestamp,
				   (token == NULL ? "" : " oauth_token=\""), (token == NULL ? "" : token), (token == NULL ? "" : "\","),
				   enc_b64_sig);
	auth_header_len++;
	auth_header = static_cast<char *>(calloc(auth_header_len, sizeof(char)));
	if(auth_header == NULL) alloc_error("HTTP Authorization buffer", auth_header_len);
	snprintf(auth_header, auth_header_len, "OAuth Realm=\"\",%s%s%s oauth_nonce=\"%s\", oauth_signature_method=\"%s\", oauth_timestamp=\"%s\",%s%s%s oauth_version=\"1.0\", oauth_signature=\"%s\"",
		 (consumer_key == NULL ? "" : " oauth_consumer_key=\""), (consumer_key == NULL ? "" : consumer_key), (consumer_key == NULL ? "" : "\","),
		 nonce, sigmeth_enum_to_str(sig_method), timestamp,
		 (token == NULL ? "" : " oauth_token=\""), (token == NULL ? "" : token), (token == NULL ? "" : "\","),
		 enc_b64_sig);
	
	http_header("Authorization", strdup(auth_header));
	
	free(auth_header);
	free(signature);
	free(key);
	free(sig_base);
	free(timestamp);
	free(base_uri);
	free(enc_params);
	free(encoded_uri);
	free(enc_b64_sig);
	free(stripped_uri);
	
	delete param_dict;
	
	sig_base = NULL;
	
	return true;
}
Esempio n. 16
0
/* Get file size and other information					*/
int conn_info( conn_t *conn )
{
	/* It's all a bit messed up.. But it works.			*/
	if( conn->proto == PROTO_FTP && !conn->proxy )
	{
		ftp_command( conn->ftp, "REST %lld", 1 );
		if( ftp_wait( conn->ftp ) / 100 == 3 ||
		    conn->ftp->status / 100 == 2 )
		{
			conn->supported = 1;
			ftp_command( conn->ftp, "REST %lld", 0 );
			ftp_wait( conn->ftp );
		}
		else
		{
			conn->supported = 0;
		}
		
		if( !ftp_cwd( conn->ftp, conn->dir ) )
			return( 0 );
		conn->size = ftp_size( conn->ftp, conn->file, MAX_REDIR );
		if( conn->size < 0 )
			conn->supported = 0;
		if( conn->size == -1 )
			return( 0 );
		else if( conn->size == -2 )
			conn->size = INT_MAX;
	}
	else
	{
		char s[MAX_STRING], *t;
		long long int i = 0;
		
		do
		{
			conn->currentbyte = 1;
			if( !conn_setup( conn ) )
				return( 0 );
			conn_exec( conn );
			conn_disconnect( conn );
			/* Code 3xx == redirect				*/
			if( conn->http->status / 100 != 3 )
				break;
			if( ( t = http_header( conn->http, "location:" ) ) == NULL )
				return( 0 );
			sscanf( t, "%1023s", s );  // Warning: truncating to MAX_STRING
			if( strstr( s, "://" ) == NULL)
			{
				sprintf( conn->http->headers, "%s%s",
					conn_url( conn ), s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			else if( s[0] == '/' )
			{
				sprintf( conn->http->headers, "http://%s:%i%s",
					conn->host, conn->port, s );
				strncpy( s, conn->http->headers, MAX_STRING );
			}
			conn_set( conn, s );
			i ++;
		}
		while( conn->http->status / 100 == 3 && i < MAX_REDIR );
		
		if( i == MAX_REDIR )
		{
			sprintf( conn->message, _("Too many redirects.\n") );
			return( 0 );
		}
		
		conn->size = http_size( conn->http );
		if( conn->http->status == 206 && conn->size >= 0 )
		{
			conn->supported = 1;
			conn->size ++;
		}
		else if( conn->http->status == 200 || conn->http->status == 206 )
		{
			conn->supported = 0;
			conn->size = INT_MAX;
		}
		else
		{
			t = strchr( conn->message, '\n' );
			if( t == NULL )
				sprintf( conn->message, _("Unknown HTTP error.\n") );
			else
				*t = 0;
			return( 0 );
		}
	}
	
	return( 1 );
}
Esempio n. 17
0
int main(int argc, char *argv[])
{
	char * op=(char *)0;
	char * search=(char *)0;
	char * searchdec=(char *)0;
	char * exact=(char *)0;

	gpgme_ctx_t gpgctx;
	gpgme_key_t gpgkey;
	gpgme_error_t gpgerr;
	gpgme_engine_info_t enginfo;

	char * qstring, * pchar;

	pchar=getenv("QUERY_STRING");
	if (! pchar || *pchar == '\0' ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: there is no query string.</h1></body></html>");
		return 1;
	}
	qstring=strndup(pchar,QSTRING_MAX); /* copy the QUERY from env to write in */
	pchar=qstring;

	while (pchar && *pchar) {
		if (!strncmp(pchar,"op=",3)) {
			pchar+=3;
			op=pchar;
		} else if (!strncmp(pchar,"search=",7)) {
			pchar+=7;
			search=pchar;
		} else if (!strncmp(pchar,"options=",8)) {
			/*this parameter is useless now, as today we only support "mr" option and always enable it (machine readable) */
			pchar+=8;
			//options=pchar;
		} else if (!strncmp(pchar,"fingerprint=",12)) {
			/*this parameter is useless now as we only support "mr" options which don't care this */
			pchar+=12;
			//fingerprints=pchar;
		} else if (!strncmp(pchar,"exact=",6)) {
			pchar+=6;
			exact=pchar;
		} /*else: Other parameter not in hkp draft are quietly ignored */
		pchar=strchr(pchar,'&');
		if (pchar) {
			*pchar='\0';
			pchar++;
		}
	}

	if (exact) {
		if (!strcmp(exact,"off")) {
			exact=(char *) 0; /* off is default */
		} else if (!strcmp(exact,"on")) {
			http_header(501,CTYPE_HTML_STR);
			printf("<html><head><title>Not implemented</title></head><body><h1>Error handling request: \"exact\" parameter is not implemented.</h1></body></html>");
			return 1;
		} else {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: \"exact\" parameter only take \"on\" or \"off\" as argument.</h1></body></html>");
			return 1;
		}
	}

	if ( ! search ) { 
		/* (mandatory parameter) */
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: Missing \"search\" parameter in \"%s\".</h1></body></html>",getenv("QUERY_STRING"));
		return 1;
	} else {
		if (searchdec=malloc(strlen(search)*sizeof(char)+1)) 
			strdecode(searchdec,search);
		else {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Internal malloc(%d) for search fail.</h1></body></html>",strlen(search)*sizeof(char)+1);
			return 1;
		}
	}

	if ( ! op )
		op="index"; /* defaut operation */

	/* Check gpgme version ( http://www.gnupg.org/documentation/manuals/gpgme/Library-Version-Check.html )*/
	setlocale (LC_ALL, "");
	gpgme_check_version (NULL);
	gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
	/* check for OpenPGP support */
	gpgerr=gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
	if ( gpgerr  != GPG_ERR_NO_ERROR ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_engine_check_version).</h1></body></html>");
		return 1;
	}

	/* create context */
	gpgerr=gpgme_new(&gpgctx);
	if ( gpgerr  != GPG_ERR_NO_ERROR ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_new %d).</h1></body></html>",gpgerr);
		return 1;
	}
	/*gpgerr = gpgme_get_engine_info(&enginfo);
	gpgerr |= gpgme_ctx_set_engine_info(gpgctx, GPGME_PROTOCOL_OpenPGP, enginfo->file_name,"../../new");
	if ( gpgerr  != GPG_ERR_NO_ERROR ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_ctx_set_engine_info %d).</h1></body></html>",gpgerr);
		return 1;
	}*/

	if (!strcmp(op, "get")) {
		gpgme_data_t gpgdata;
		char buff[BUFFSIZE];
		ssize_t read_bytes;

		gpgme_set_armor(gpgctx,1);
		gpgerr = gpgme_data_new(&gpgdata);
		if (gpgerr == GPG_ERR_NO_ERROR) {
			gpgerr = gpgme_data_set_encoding(gpgdata,GPGME_DATA_ENCODING_ARMOR);
			if (gpgerr == GPG_ERR_NO_ERROR)
				gpgerr = gpgme_op_export(gpgctx,searchdec,0,gpgdata);
		}

		if ( gpgerr != GPG_ERR_NO_ERROR) {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (%d).</h1></body></html>",gpgerr);
			return 1;
		}
		gpgme_data_seek (gpgdata, 0, SEEK_SET);
		read_bytes = gpgme_data_read (gpgdata, buff, BUFFSIZE);
		if ( read_bytes == -1 ) {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (%s).</h1></body></html>",gpgme_strerror(errno));
			return 1;
		} else if ( read_bytes <= 0 ) {
			http_header(404,CTYPE_HTML_STR);
			printf("<html><head><title>ludd Public Key Server -- Get: %s</title></head><body><h1>Public Key Server -- Get: %s : No key found ! :-( </h1></body></html>",search,search);
			return 0;
		} else {
			http_header(200,CTYPE_HTML_STR);
			printf("<html><head><title>ludd Public Key Server -- Get: %s</title></head><body><h1>Public Key Server -- Get: %s</h1><pre>",search,search);
			fwrite(buff, sizeof(char),read_bytes,stdout); /* Now it's too late to test fwrite return value ;-) */ 
			while ( (read_bytes = gpgme_data_read (gpgdata, buff, BUFFSIZE)) > 0 )
				fwrite(buff, sizeof(char),read_bytes,stdout);
			printf("\n</pre></body></html>");
			return 0;
		}

	} else if (!strcmp(op, "index")) {
		char uidenc[BUFFSIZE];
		char begin=0;
		gpgme_user_id_t gpguid;

		/* check for the searched key(s) */
		gpgerr = gpgme_op_keylist_start(gpgctx, searchdec, 0);
		//gpgerr = gpgme_op_keylist_start(gpgctx, NULL, 0);
		if ( gpgerr  != GPG_ERR_NO_ERROR ) {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_op_keylist_start %d).</h1></body></html>",gpgerr);
			return 1;
		}

		gpgerr = gpgme_op_keylist_next (gpgctx, &gpgkey);
		while (gpgerr == GPG_ERR_NO_ERROR) {
			if (!begin) {
				http_header(200,"text/plain; charset=utf-8");
				begin=1;
				/* Luckily: info "header" is optionnal, see draft-shaw-openpgp-hkp-00.txt */
			}
			/* first subkey is the main key */
			printf("pub:%s:%d:%d:%d:%d\n",gpgkey->subkeys->fpr,gpgkey->subkeys->pubkey_algo,gpgkey->subkeys->length,gpgkey->subkeys->timestamp,(gpgkey->subkeys->expires?gpgkey->subkeys->expires:-1));
			gpguid=gpgkey->uids;
			while (gpguid) {
				printf("uid:%s (%s) <%s>:\n",gpguid->name,gpguid->comment,gpguid->email);
				gpguid=gpguid->next;
			}
			gpgme_key_unref(gpgkey);
			gpgerr = gpgme_op_keylist_next (gpgctx, &gpgkey);
		}
			gpgme_key_unref(gpgkey); /* ... because i don't know how "gpgme_op_keylist_next" behave when not returning GPG_ERR_NO_ERROR */
		if (!begin) {
			http_header(404,CTYPE_HTML_STR);
			printf("<html><head><title>ludd Public Key Server -- index: %s</title></head><body><h1>index Error: No keys found</h1></body></html>",search);
			return 1;
		}
		return 0;

	} else if ( !strcmp(op, "photo") || !strcmp(op, "x-photo") ) {
			http_header(501,CTYPE_HTML_STR);
			printf("<html><head><title>Not implemented</title></head><body><h1>Error handling request: \"%s\" operation is not implemented.</h1></body></html>",op);
			return 1;
	} else {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: Unrecognized action in \"%s\".</h1></body></html>",getenv("QUERY_STRING"));
		return 1;
	}
}
Esempio n. 18
0
ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) {
  ssize_t reply_off, len;
  char   *read_ptr = ws->request, *write_ptr;

#ifdef WANT_FULLLOG_NETWORKS
  struct http_data *cookie = io_getcookie( sock );
  if( loglist_check_address( cookie->ip ) ) {
    ot_log *log = malloc( sizeof( ot_log ) );
    if( log ) {
      log->size = ws->request_size;
      log->data = malloc( ws->request_size );
      log->next = 0;
      log->time = g_now_seconds;
      memcpy( log->ip, cookie->ip, sizeof(ot_ip6));
      if( log->data ) {
        memcpy( log->data, ws->request, ws->request_size );
        if( !g_logchain_first )
          g_logchain_first = g_logchain_last = log;
        else {
          g_logchain_last->next = log;
          g_logchain_last = log;  
        }        
      } else
        free( log );
    }
  }
#endif

#ifdef _DEBUG_HTTPERROR
  reply_off = ws->request_size;
  if( ws->request_size >= G_DEBUGBUF_SIZE )
    reply_off = G_DEBUGBUF_SIZE - 1;
  memcpy( ws->debugbuf, ws->request, reply_off );
  ws->debugbuf[ reply_off ] = 0;
#endif
  
  /* Tell subroutines where to put reply data */
  ws->reply = ws->outbuf + SUCCESS_HTTP_HEADER_LENGTH;

  /* This one implicitely tests strlen < 5, too -- remember, it is \n terminated */
  if( memcmp( read_ptr, "GET /", 5) ) HTTPERROR_400;

  /* Skip leading '/' */
  for( read_ptr+=4; *read_ptr == '/'; ++read_ptr);

  /* Try to parse the request.
     In reality we abandoned requiring the url to be correct. This now
     only decodes url encoded characters, we check for announces and
     scrapes by looking for "a*" or "sc" */
  len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_PATH );

  /* If parsing returned an error, leave with not found */
  if( g_redirecturl && ( len == -2 ) ) HTTPERROR_302;
  if( len <= 0 ) HTTPERROR_404;

  /* This is the hardcore match for announce*/
  if( ( *write_ptr == 'a' ) || ( *write_ptr == '?' ) )
    http_handle_announce( sock, ws, read_ptr );
#ifdef WANT_FULLSCRAPE
  else if( !memcmp( write_ptr, "scrape HTTP/", 12 ) )
    http_handle_fullscrape( sock, ws );
#endif
  /* This is the hardcore match for scrape */
  else if( !memcmp( write_ptr, "sc", 2 ) )
    http_handle_scrape( sock, ws, read_ptr );
  /* All the rest is matched the standard way */
  else if( len == g_stats_path_len && !memcmp( write_ptr, g_stats_path, len ) )
    http_handle_stats( sock, ws, read_ptr );
  else
    HTTPERROR_404;

  /* Find out if the client wants to keep this connection alive */
  ws->keep_alive = 0;
#ifdef WANT_KEEPALIVE
  read_ptr=http_header( ws->request, ws->header_size, "connection");
  if( read_ptr && ( *read_ptr == 'K' || *read_ptr == 'k' ) ) ws->keep_alive = 1;
#endif

  /* If routines handled sending themselves, just return */
  if( ws->reply_size == -2 ) return 0;
  /* If routine failed, let http error take over */
  if( ws->reply_size <= 0 ) HTTPERROR_500;

  /* This one is rather ugly, so I take you step by step through it.

     1. In order to avoid having two buffers, one for header and one for content, we allow all above functions from trackerlogic to
     write to a fixed location, leaving SUCCESS_HTTP_HEADER_LENGTH bytes in our work buffer, which is enough for the static string
     plus dynamic space needed to expand our Content-Length value. We reserve SUCCESS_HTTP_SIZE_OFF for its expansion and calculate
     the space NOT needed to expand in reply_off
  */
  reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( ws->outbuf, 0, "%zd", ws->reply_size );
  ws->reply = ws->outbuf + reply_off;

  /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete
     packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */
  ws->reply_size += 1 + sprintf( ws->reply, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", ws->reply_size );

  /* 3. Finally we join both blocks neatly */
  ws->outbuf[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n';

  http_senddata( sock, ws );
  return ws->reply_size;
}
Esempio n. 19
0
int
do_search(
    REQUEST         *r,
    RESPONSE        *resp
)
{
    char            *filtertype, **search_attrs, *search_filter;
    char            *print_filter, *human_filter;
    int             scope, count = 0, rc, i = 0, j, in_home;
    int option_param;
    struct timeval  timeout;
    LDAPFiltInfo    *fi;
    LDAPMessage     *e, *res;
    static char     *def_attrs[] = 
                {"objectClass", "sn", "aliasedObjectName", "labeledURI", 0};
    struct ldap_disptmpl    *tmpl;
    char    **oc;
    char    *result_dn, *doc, *foc, *url_dn;
    char    *base_dn, *base_ufn, *result_ufn, *alias_ufn, *sortstring, *cp, *bp;
    char    **sn, href[10 * BUFSIZ], *temp, **val, *server = NULL;
    int     counter = 0, base_len, isalias = 0;

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "do_search (%s, %s, (",
        r->r_dn, flag2string(r->r_flags), 0, 0);
    while (r->r_attrs && r->r_attrs[i]) {
        Web500gw_debug(WEB500GW_DEBUG_TRACE, "%s ", r->r_attrs[i], 0, 0, 0);
        i++;
    }
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "), %s)\n", 
        (r->r_filter && *r->r_filter) ? r->r_filter : "No filter", 0, 0, 0);
#endif

    if (r->r_ld == (LDAP *)0 &&
        (r->r_ld = web500gw_ldap_init(r, resp, NULL, NULL, 1)) == NULL)
        return NOTOK;

    base_dn = r->r_dn;
    if (strlen(base_dn) > 0) {
        base_ufn = friendly_dn(resp, base_dn);
    } else {
        base_ufn = NULL;
    }
    base_len = base_ufn ? strlen(base_ufn) : 0;


    if (r->r_filter == NULL) {
        return NOTOK;
    }
    print_filter = r->r_filter;
#if defined(OWN_STR_TRANSLATION)
    search_filter = strdup(web500gw_isotot61(r->r_filter));
#else
    search_filter = r->r_filter;
#endif
    if (*search_filter == '\0' || *(search_filter+1) != '=') {
        scope = LDAP_SCOPE_ONELEVEL;
    } else {
        if (*search_filter == 'S') {
            scope = LDAP_SCOPE_SUBTREE;
        } else {
            scope = LDAP_SCOPE_ONELEVEL;
        }
        search_filter += 2;
        print_filter += 2;
    }

    /* make a "human readable filter" - for now, no artistic things are done */
    human_filter = print_filter;
    if ((cp = strchr(print_filter, '=')) != NULL) {
        if ((cp = strchr(cp+1, '=')) != NULL) {
            /* two '=' in it - must be a complex filter - isn't readable... */
            human_filter = MSG_COMPLEX_FILTER;
        }
    }

    if (*search_filter) {   /* not the default filter */
        r->r_flags |= FLAG_FILTER;
                            /* skip leading white spaces */
        while (isspace(*search_filter)) ++search_filter;
    }
    if (r->r_attrs == NULL || *r->r_attrs == NULL) {
        /* No attributes requested - read default attrs for sorting */
        search_attrs = def_attrs;
    } else {
        j = 0;
        while (def_attrs[j]) j++;
        search_attrs = (char **) calloc(r->r_attrnumb + j + 1, sizeof(char *));
        i = j = 0;
        while (r->r_attrs && r->r_attrs[i])  {
            search_attrs[i] = r->r_attrs[i];
            i++;
        }
        while (def_attrs[j]) 
            search_attrs[i++] = def_attrs[j++];    
        search_attrs[i] = NULL;
    }

    if ((in_home = isinhome(base_dn)))
        /* ACCESS sizelimit if searching below HOME DN */
        ldap_set_option(r->r_ld, LDAP_OPT_SIZELIMIT, &(r->r_access->a_sizelimit));
    else
        ldap_set_option(r->r_ld, LDAP_OPT_SIZELIMIT, &sizelimit);

    /* A simple filter (not starting with '(') with a comma in it 
     *  -> UFN assumed */

    /*    if (ufnsearch && search_filter[0] != '(' && 
        strchr(search_filter, ',') != NULL && strlen(search_filter) > 3) {
        if (strlen(base_dn) > 0)
            ldap_ufn_setprefix(r->r_ld, base_dn);
        timeout.tv_sec = timelimit;
        timeout.tv_usec = 0;
        ldap_ufn_timeout((void *) &timeout);

	option_param = LDAP_DEREF_FINDING;
	ldap_set_option(r->r_ld, LDAP_OPT_DEREF, (void *) &option_param);
#ifdef WEB500GW_DEBUG
        Web500gw_debug(WEB500GW_DEBUG_TRACE, "ldap_ufn_search_s (%s)\n", 
            search_filter, 0, 0, 0);
#endif
        if ((rc = ldap_ufn_search_s(r->r_ld, search_filter, search_attrs, 0, &res))
            != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED) {
            do_error(r, resp, rc, 0, get_ldap_result_code(r->r_ld), get_ldap_matched_str(r->r_ld));
            return NOTOK;
        }
        count = ldap_count_entries(r->r_ld, res);
#ifdef WEB500GW_DEBUG
        Web500gw_debug(WEB500GW_DEBUG_TRACE, "UFN ready: %d results!\n",
            count, 0, 0, 0);
#endif
        // Reset DN, because this UFN search was probably not below DN
        base_dn = base_ufn = "";
        in_home = 0;

        friendlyDesc = MSG_UFN;

	} else { */
        /* let's do the search */
        filtertype = (scope == LDAP_SCOPE_ONELEVEL ? "web500gw onelevel" :
            "web500gw subtree");

	option_param = (scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING : LDAP_DEREF_ALWAYS);

	ldap_set_option(r->r_ld, LDAP_OPT_DEREF, 
			(void *) &option_param);
        timeout.tv_sec = timelimit;
        timeout.tv_usec = 0;
    
        friendlyDesc = NULL;

        /* try all filters til we have success */
        for (fi = ldap_getfirstfilter(r->r_access->a_filtd, filtertype, search_filter);
            fi != NULL; fi = ldap_getnextfilter(r->r_access->a_filtd)) {
#ifdef WEB500GW_DEBUG
            Web500gw_debug(WEB500GW_DEBUG_FILTER, "  search %s: %s -- %s\n",
                scope == LDAP_SCOPE_ONELEVEL ? "onelevel" : "subtree",
                fi->lfi_filter, fi->lfi_desc, 0);
#endif
            if ((rc = ldap_search_st(r->r_ld, base_dn, scope, fi->lfi_filter,
                search_attrs, 0, &timeout, &res)) != LDAP_SUCCESS && 
                rc != LDAP_SIZELIMIT_EXCEEDED && rc != LDAP_INSUFFICIENT_ACCESS 
                && rc != LDAP_TIMELIMIT_EXCEEDED && rc != LDAP_TIMEOUT
                && rc != LDAP_PARTIAL_RESULTS) {
                do_error(r, resp, rc, 0, get_ldap_result_code(r->r_ld), get_ldap_matched_str(r->r_ld));
                return NOTOK;
            }
            if ((count = ldap_count_entries(r->r_ld, res)) > 0) {
                /* found something */
                friendlyDesc = friendly_label(resp, fi->lfi_desc);
#ifdef WEB500GW_DEBUG
                Web500gw_debug(WEB500GW_DEBUG_FILTER, 
                    " searched ... and found %d results!\n", count, 0, 0, 0);
#endif
                break;
            }
#ifdef WEB500GW_DEBUG
            Web500gw_debug(WEB500GW_DEBUG_FILTER, 
                " searched ... and found no results!\n", 0, 0, 0, 0);
#endif
        }
	option_param = LDAP_DEREF_ALWAYS;
	ldap_set_option(r->r_ld, LDAP_OPT_DEREF, (void *) &option_param);
	/* }*/

    if (count < 1) {        /* nothing found :-( */
        if (r->r_flags & FLAG_SEARCHACT) {
            /* in a search action we silently ignore this */
            return OK;
        }

        resp->resp_status = NOT_FOUND;
        if (resp->resp_httpheader == 0) {
            if (r->r_httpversion == 1) {
                /* Expires now */
                resp->resp_expires = 0;
                http_header(r, resp);
            }
            if (r->r_method == HEAD) {
                return OK;
            }
        }
        if (resp->resp_htmlheader == 0) {
            msg_fprintf(fp, in_home && *MSG_HTML_START_NO_SEARCH_RESULTS_HOME
            ? MSG_HTML_START_NO_SEARCH_RESULTS_HOME : MSG_HTML_START_NO_SEARCH_RESULTS, 
                "ss", print_filter, base_ufn ? base_ufn : MSG_ROOT);
            resp->resp_htmlheader = 1;

            if (!(r->r_flags & FLAG_ENTRYONLY)) {
                if (in_home && MSG_HOMEBANNER) {
                    msg_fprintf(fp, MSG_HOMEBANNER, "sss", r->r_query,
                        other_lang_select, other_lang_string);
                } else {
                    msg_fprintf(fp, MSG_BANNER, "sss", r->r_query,
                        other_lang_select, other_lang_string);
                }
            }
            if (rc == LDAP_INSUFFICIENT_ACCESS) {
                fputs(MSG_NO_LIST_ACCESS, fp);
            } else if (rc == LDAP_TIMELIMIT_EXCEEDED || rc == LDAP_TIMEOUT) {
                fputs(MSG_TIMELIMIT, fp);
            } else {
                if (print_filter && *print_filter) {
                    msg_fprintf(fp, MSG_NO_SEARCH_RESULTS, "ssss",
                    (scope == LDAP_SCOPE_ONELEVEL ?  MSG_ONELEVEL : MSG_SUBTREE),
                    print_filter, human_filter, base_ufn ? base_ufn : MSG_ROOT);
                } else {
                    fputs(MSG_NOTHING_FOUND_READORSEARCH, fp);
                }
            }
            if (!(r->r_flags & FLAG_ENTRYONLY)) {
                make_upsearch(r->r_ld, r, resp, 1);
                if (in_home && MSG_HOMETRAILER) {
                    fputs(MSG_HOMETRAILER, fp);
                } else {
                    fputs(MSG_TRAILER, fp);
                }
            }
            fputs(MSG_HTML_END, fp);
            fputs("\n", fp);
        } else {        
            /* resp->resp_htmlheader != 0 -> within a document (searchaction) */
            if (rc == LDAP_INSUFFICIENT_ACCESS) {
                fputs(MSG_NO_LIST_ACCESS, fp);
            } else if (rc == LDAP_TIMELIMIT_EXCEEDED || rc == LDAP_TIMEOUT) {
                fputs(MSG_TIMELIMIT, fp);
            } else {
                fputs(MSG_NOTHING_FOUND_READORSEARCH, fp);
                fputs(MSG_HTML_END, fp);
                fputs("\n", fp);
            }
        }
        return OK;
    }
    if (showonematch == 1 && count == 1 && r->r_attrnumb == 0 &&
        !(r->r_flags & FLAG_SEARCHACT)) {
    /* header != 0 ? */
        /* only one result and not searching for special attrs (searchaction) */
        e = ldap_first_entry(r->r_ld, res);
        if (e != NULL) {
            char **oc, **aliasdn;
            oc = ldap_get_values(r->r_ld, e, objectclass_attr);
            aliasdn = ldap_get_values(r->r_ld, e, "aliasedObjectName");
            if (aliasdn && *aliasdn)
                result_dn = *aliasdn;
            else
                result_dn = ldap_get_dn(r->r_ld, e);
            if (result_dn) {
                result_ufn = friendly_dn(resp, result_dn);
                if (gwswitch) {
                    server = gw_switch(r->r_ld, resp, e);
                }
                r->r_flags &= ~FLAG_FILTER;    /* it's not a search anymore */
                url_dn = dn2url(r, result_dn, 
                          server ? r->r_flags & ~FLAG_LANGUAGE : r->r_flags, 
                          0, NULL, server);

                /* Redirect */
#ifdef WEB500GW_DEBUG
                Web500gw_debug(WEB500GW_DEBUG_TRACE, 
                    "do_search: found one entry -> REDIRECT: %s\n",
                         url_dn, 0, 0, 0);
#endif
                resp->resp_status = REDIRECT;
                if (resp->resp_httpheader == 0 && r->r_httpversion == 1) {
                    resp->resp_location = malloc(strlen(url_dn) + 11);
                    strcpy(resp->resp_location, url_dn);

                    http_header(r, resp);
                    /* free(resp->resp_location); */
                }
                if (r->r_method == HEAD) {
                    return OK;
                }
                msg_fprintf(fp, in_home && *MSG_HTML_START_SEARCH_RESULTS_HOME ?
                MSG_HTML_START_SEARCH_RESULTS_HOME : MSG_HTML_START_SEARCH_RESULTS, 
                    "ss", print_filter, result_ufn);
                msg_fprintf(fp, MSG_REDIRECT, "ss", url_dn, result_ufn);
                fputs(MSG_HTML_END, fp);
                fputs("\n", fp);
                return OK;
            }
        }
    }

    /* Found something */
    /* Prepare HTTP + HTML header */
    if (resp->resp_httpheader == 0 && r->r_httpversion == 1) {
        http_header(r, resp);
        if (r->r_method == HEAD)
            return OK;
    }
    if (resp->resp_htmlheader == 0) {
        msg_fprintf(fp, in_home && *MSG_HTML_START_SEARCH_RESULTS_HOME ?
            MSG_HTML_START_SEARCH_RESULTS_HOME : MSG_HTML_START_SEARCH_RESULTS, 
            "ss", print_filter, base_ufn ? base_ufn : MSG_ROOT);
        if (!(r->r_flags & FLAG_ENTRYONLY)) {
            if (in_home && MSG_HOMEBANNER) {
                msg_fprintf(fp, MSG_HOMEBANNER, "sss", r->r_query,
                    other_lang_select, other_lang_string);
            } else {
                msg_fprintf(fp, MSG_BANNER, "sss", r->r_query,
                    other_lang_select, other_lang_string);
            }
        }
        resp->resp_htmlheader = 1;
    }
    if ((!(r->r_flags & FLAG_ENTRYONLY)) && 
        (r->r_browser->b_upsearch & UPSEARCH_ON_TOP)) {
        make_upsearch(r->r_ld, r, resp, 1);
    }
    if (r->r_flags & FLAG_FILTER && 
        (!(r->r_flags & FLAG_ENTRYONLY))) {
        /* Not the default filter and not entryonly */

        msg_fprintf(fp, MSG_SEARCH_RESULTS, "ssssisss",
            (scope == LDAP_SCOPE_ONELEVEL ?  MSG_ONELEVEL : MSG_SUBTREE),
            print_filter, human_filter, 
            base_ufn && *base_ufn ? base_ufn : MSG_ROOT,
            count, count == 1 ? MSG_ENTRY : MSG_ENTRIES, friendlyDesc,
            rc == LDAP_PARTIAL_RESULTS ?
            resp->resp_language->l_conf->c_errmsg[LDAP_PARTIAL_RESULTS] : "");
    }
    if (ldap_result2error(r->r_ld, res, 0) == LDAP_SIZELIMIT_EXCEEDED) {
        fprintf(fp, r->r_flags & FLAG_FILTER && r->r_access->a_sizelimit == 0 ? 
            MSG_SIZELIMIT_1 : MSG_SIZELIMIT_0, count);
    }
    
    /* Now prepare the result for sorting */ 

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, 
        "do_search: preparing for sort\n", 0, 0, 0, 0);
#endif

    /* for all the results ... */
    for (e = ldap_first_entry(r->r_ld, res); e != NULL && counter < MAX_LISTSIZE; 
         e = ldap_next_entry(r->r_ld, e)) {

        result_dn = ldap_get_dn(r->r_ld, e);
        result_ufn = friendly_dn(resp, result_dn);
        if ((val = ldap_get_values(r->r_ld, e, "aliasedObjectName"))) {
            /* entry is alias */
            free(result_dn);
            result_dn = strdup(*val);
            alias_ufn = friendly_dn(resp, result_dn);
            ldap_value_free(val);
            isalias = 1;
        } else {
            isalias = 0;
        }
        if (isalias && r->r_flags & FLAG_DEREFALIAS) {
            /* if alias, look for objectClass of real entry */
            oc = deref(r->r_ld, result_dn);
        } else {
            oc = ldap_get_values(r->r_ld, e, objectclass_attr);
        }
            
        /* find template to see the plural name of the objectclass */
        tmpl = ldap_oc2template(oc, r->r_access->a_tmpllist);
        doc = pick_oc(oc);
        if (tmpl && tmpl->dt_pluralname) {
            foc = strdup(friendly_label(resp, tmpl->dt_pluralname));
        } else {
            foc = strdup(friendly_label(resp, doc));
            if (strcmp(foc, doc) == 0) {
            /* "no friendly objectclass" found -> last in the list (a hack) */
                foc = (char *)malloc(strlen(doc)+9);
                sprintf(foc, "&#032;%s", doc);
            }
        }
        if (strncasecmp(result_ufn, "{ASN}", 5) == 0) {
            /* ASNs are not something we want to display! */
            free(result_dn);
            ldap_value_free(oc);
            continue;
        }
        if (base_len > 0) {
            /* strip search base from result */
            result_ufn = strip_ufn_dn(result_ufn, base_ufn);
        }
#ifdef nodef
            cp = result_ufn + strlen(result_ufn) - 1;
            bp = base_ufn + base_len - 1;
            while (bp >= base_ufn && *cp-- && *bp-- && *cp == *bp);
            
            if ((bp+1) == base_ufn && cp != NULL) { /* Complete match on base */
                /* strip trailing whitespaces and ',' */
                while (*cp && isspace(*cp)) cp--;
                if (cp != NULL && *cp == ',')
                    *cp = '\0';
            }
        }
#endif
        
        sortstring = strdup(result_ufn);
        if (strcasecmp(doc, "country") == 0) {  /* a country */
            sn = NULL;
        } else {                                /* not a country */
            /* DNs may have components in '"', ignored  when sorting */
            if (*sortstring == '"') {
                sortstring++;
                cp = strchr(sortstring+1, '"');
            } else {
                cp = sortstring;
            }
            if ((cp = strchr(cp,',')))
                *cp = '\0';
            if (isalias) {      /* aliases don't have surnames */
                if (isoc (oc, "person")) {
                }
            }
            sn = ldap_get_values(r->r_ld, e, "sn");
/*  Delete spaces ???
            if (sn) {
                cp = *sn;
                while ((cp = strchr(cp,' '))) {
                    cp ++;
                    spaces ++;
                }
            }
            while (spaces > 0) {
                if ((cp = strrchr(sortstring,' '))) {
                    *cp = '\0';
                    spaces --;
                } else
                    break;
            }
*/
            if ((cp = strchr(sortstring,'+'))) {
                cp --;
                *cp = '\0';
            }
        }

        if (gwswitch) {
            server = gw_switch(r->r_ld, resp, e);
        }
        /* build the link (HREF) */
        if (isalias) {
            if (isnonleaf(r->r_ld, oc, result_dn)) {
                if (r->r_flags & FLAG_NOHREFDN)
                    msg_snprintf(href, sizeof(href), MSG_DN_ALIAS_TO_NONLEAF, 
                        "sss", result_ufn, alias_ufn, html_encode(result_dn));
                else
                    msg_snprintf(href, sizeof(href), MSG_HREF_ALIAS_TO_NONLEAF,
                        "ssssss",
                        dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE,
                        0, NULL, server), result_ufn,
                        alias_ufn, html_encode(result_dn),
                        string_encode(result_ufn),string_encode(result_dn));
            } else {
                if (r->r_flags & FLAG_NOHREFDN)
                    msg_snprintf(href, sizeof(href), MSG_DN_ALIAS_TO_LEAF, 
                        "sss",
                        result_ufn, alias_ufn, html_encode(result_dn));
                else
                    msg_snprintf(href, sizeof(href), MSG_HREF_ALIAS_TO_LEAF,
                        "ssssss",
                        dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE, 0, NULL,
                        server), result_ufn,
                        alias_ufn, html_encode(result_dn),
                        string_encode(result_ufn),string_encode(result_dn));
            }
        } else if (isnonleaf(r->r_ld, oc, result_dn)) {
            if (r->r_flags & FLAG_NOHREFDN)
                msg_snprintf(href, sizeof(href), MSG_DN_NON_LEAF, "ss",
                    result_ufn, html_encode(result_dn));
            else
                msg_snprintf(href, sizeof(href), MSG_HREF_NON_LEAF, "sssss",
                    dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE, 0,
                    NULL, server), result_ufn,
                    html_encode(result_dn), string_encode(result_ufn),
                    string_encode(result_dn));
        } else {
            if (r->r_flags & FLAG_NOHREFDN)
                msg_snprintf(href, sizeof(href), MSG_DN_LEAF, "ss",
                    result_ufn, html_encode(result_dn));
            else
                msg_snprintf(href, sizeof(href), MSG_HREF_LEAF, "sssss",
                    dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE, 0,
                    NULL, server), result_ufn, 
                    html_encode(result_dn), string_encode(result_ufn),
                    string_encode(result_dn));
        }
        /* build the sortstring:  foc[sn]sortstring */
        if (sn) {
            temp = (char *) malloc(strlen(foc)+strlen(*sn)+strlen(sortstring)+1);
        } else {
            temp = (char *) malloc(strlen(foc)+strlen(sortstring)+1);
        }
        strcpy(temp, foc);
        if (sn) {
            strcat(temp, *sn);
        }
        strcat(temp, sortstring);
        if (!dnlist[counter]) {
            dnlist[counter] = (struct dncompare *) malloc(sizeof(struct dncompare));
        }
        dnlist[counter]->sortstring = temp;
        dnlist[counter]->href = strdup(href);
        dnlist[counter]->friendly_oc = foc;
        dnlist[counter]->oc = doc;
        dnlist[counter]->tmpl = tmpl;
        dnlist[counter]->entry = e;
        dnlist[counter]->dn = strdup(result_dn);
        counter++;
        ldap_value_free(oc);
        free(result_dn);
        if (sn)
            ldap_value_free(sn);
    }
Esempio n. 20
0
int
do_addform(
    REQUEST     *r,
    RESPONSE    *resp
)
{
#ifndef MODIFY
    do_error(r, resp, LDAP_OTHER, NOT_IMPLEMENTED, MSG_NOT_SUPPORTED, NULL);
    return NOTOK;
#else   /* defined MODIFY */

    int             rc, in_home;
    char            *bind_as, *pw, *args, *tmpl, *basedn, *rdn, *ufn, *cp;
    LDAPMessage     *res;
    struct timeval  timeout;
    struct ldap_disptmpl    *templ;


/* 
 * query = default Base-DN, 
 * args = dn=BindDN&userPassword=PASSWD&tmpl=template&basedn=DN
 */
    args = r->r_method == POST ? r->r_postdata : r->r_filter;

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "do_addform (%s, %s)\n",    
        r->r_dn, args ? args : "", 0, 0);
#endif

    if (args == NULL) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, NULL, NULL);
        return NOTOK;
    }
    bind_as = pw = tmpl = basedn = NULL;
    cp = args;
    while (cp && *cp) {
        if (strncmp(cp, "dn=", 3) == 0) {
            bind_as = cp + 3;
        } else if (strncmp(cp, "userPassword="******"tmpl=", 5) == 0) {
            tmpl = cp + 5;
        } else if (strncmp(cp, "basedn=", 7) == 0) {
            basedn = cp + 7;
        } /* else ignore */
        cp = strchr(cp, '&');
        if (cp && *cp)
            *cp++ = '\0';
    }
    if (!bind_as) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_NO_BIND_DN, NULL);
        return NOTOK;
    }
    hex_qdecode(bind_as);

    if (! pw) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_MISSING_PASSWORD, NULL);
        return NOTOK;
    }
    hex_qdecode(pw);
    if (basedn && *basedn) {
        hex_qdecode(basedn);
    } else {
        basedn = r->r_dn;
    }
    hex_qdecode(tmpl);
    if (tmpl && *tmpl)      /* overrides the template in URL */
        r->r_template = tmpl;
        
    if (! (r->r_template && *r->r_template)) {
        /* need a objectclass template */
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_TEMPLATE_MISSING, NULL);
        return NOTOK;
    }

/*  No bind necessary at this stage but checking it anyway to block
 *  non-admins */
    if ((!bind_as) || strlen(bind_as) == 0) { /* No DN to bind as */
        do_error (r, resp, LDAP_INAPPROPRIATE_AUTH, BAD_REQUEST, 
                 MSG_UNKNOWN_ARGUMENT, NULL);
        return NOTOK;
    }
    r->r_binddn = bind_as;
    if ((!pw) || strlen(pw) == 0) { /* we need a password for simple auth */
        do_error (r, resp, LDAP_INAPPROPRIATE_AUTH, 0, MSG_NULL_PASSWORD, NULL);
        return NOTOK;
    }

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "BINDING as %s ... ", bind_as, 0, 0, 0);
#endif
    if ((r->r_ld = web500gw_ldap_init(r, resp, bind_as, pw, 1)) == (LDAP *)0)
        return NOTOK;
#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "BOUND\n", 0, 0, 0, 0);
#endif

    /* let's see if basedn exists ... */
    timeout.tv_sec = timelimit;
    timeout.tv_usec = 0;
    if ((rc = ldap_search_st(r->r_ld, basedn, LDAP_SCOPE_BASE, default_filter,
        NULL, 0, &timeout, &res)) != LDAP_SUCCESS) {
        /* better error description here ??? */
        do_error(r, resp, rc, 0, get_ldap_error_str(r->r_ld), get_ldap_matched_str(r->r_ld));
        return NOTOK;
    }
    /* check if nonleaf here ??? */

    ufn = friendly_dn(resp, basedn);
    rdn = friendly_rdn(resp, basedn, 1);
    in_home = isinhome(basedn);
 
    /* find the requested template */
    templ = ldap_name2template(r->r_template, r->r_access->a_tmpllist);
    if (templ == NULL) {            /* template not found */
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_TEMPLATE_MISSING, NULL);
        return NOTOK;
    }
    /* .. and see if it's allowed to add such an entry */
    if (!LDAP_IS_DISPTMPL_OPTION_SET(templ, LDAP_DTMPL_OPT_ADDABLE)) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_ADD_OC_NOT_ADDABLE, NULL);
        return NOTOK;
    }

    if (r->r_httpversion == 1 && resp->resp_httpheader == 0) {
        /* Expires now - don't allow to cache */
        /* resp->resp_expires = 0; */
        http_header(r, resp);
    }
    if (resp->resp_htmlheader == 0) {
        msg_fprintf(fp, in_home && *MSG_HTML_START_MISC_HOME ?
            MSG_HTML_START_MISC_HOME : MSG_HTML_START_MISC, 
            "sss", MSG_ADD, rdn, ufn);
        resp->resp_htmlheader = 1;
    }
    msg_fprintf(fp, MSG_EXPLAIN_ADD, "ss", rdn, ufn);
    fprintf(fp, "<FORM METHOD=POST ACTION=\"%s\">\n", 
        dn2url(r, basedn, FLAG_LANGUAGE|FLAG_TMPL, ACTION_ADD, NULL, NULL));

    if (r->r_browser->b_opts & B_HIDDEN) {
        fprintf(fp, "<INPUT TYPE=\"hidden\" NAME=\"adder_dn\" VALUE=\"%s\">\n\
<INPUT TYPE=\"hidden\" NAME=\"adder_pw\" VALUE=\"%s\">\n",
	      html_encode(bind_as, strlen(bind_as)), html_encode(pw, strlen(pw)));

    } else {
Esempio n. 21
0
int bbssnd_main(void)
{
	if (!loginok)
		return BBS_ELGNREQ;
	if (parse_post_data() < 0)
		return BBS_EINVAL;
	int bid = strtol(getparm("bid"), NULL, 10);
	struct boardheader *bp = getbcache2(bid);
	if (bp == NULL || !haspostperm(&currentuser, bp))
		return BBS_ENOBRD;
	if (bp->flag & BOARD_DIR_FLAG)
		return BBS_EINVAL;

	bool isedit = (*(getparm("e")) == '1');
	unsigned int fid;
	struct fileheader fh;
	char *f = getparm("f");
	bool reply = !(*f == '\0');
	if (reply) {
		fid = strtoul(f, NULL, 10);
		if (!bbscon_search(bp, fid, 0, &fh))
			return BBS_ENOFILE;
		if (!isedit && fh.accessed[0] & FILE_NOREPLY)
			return BBS_EPST;
		if (isedit && !chkBM(bp, &currentuser)
				&& strcmp(fh.owner, currentuser.userid))
			return BBS_EACCES;
	}

	char title[sizeof(fh.title)];
	if (!isedit) {
		strlcpy(title, getparm("title"), sizeof(title));
		printable_filter(title);
		if (*title == '\0')
			return BBS_EINVAL;
	}

// TODO: ...
#ifdef SPARC
		if(abs(time(0) - *(int*)(u_info->from+34))<6) { //modified from 36 to 34 for sparc solaris by roly 02.02.28
			*(int*)(u_info->from+34)=time(0); //modified from 36 to 34 for sparc solaris by roly 02.02.28
			return BBS_EPFREQ;
		}
		*(int*)(u_info->from+34)=time(0);//modified from 36 to 34 for sparc solaris by roly 02.02.28
#else
		if(abs(time(0) - *(int*)(u_info->from+36))<6) { //modified from 36 to 34 for sparc solaris by roly 02.02.28
			*(int*)(u_info->from+36)=time(0); //modified from 36 to 34 for sparc solaris by roly 02.02.28
			return BBS_EPFREQ;
		}
		*(int*)(u_info->from+36)=time(0);//modified from 36 to 34 for sparc solaris by roly 02.02.28
#endif

	if (isedit) {
		char file[HOMELEN];
		setbfile(file, bp->filename, fh.filename);
		if (edit_article(file, getparm("text"), mask_host(fromhost)) < 0)
			return BBS_EINTNL;
	} else {
		post_request_t pr = { .autopost = false, .crosspost = false,
			.userid = NULL, .nick = NULL, .user = &currentuser,
			.bp = bp, .title = title, .content = getparm("text"),
			.sig = strtol(getparm("sig"), NULL, 0), .ip = mask_host(fromhost),
			.o_fp = reply ? &fh : NULL, .noreply = false, .mmark = false };
		if (do_post_article(&pr) < 0)
			return BBS_EINTNL;
	}

	if (!isedit && !junkboard(bp)) {
		currentuser.numposts++;
		save_user_data(&currentuser);
	}

	char buf[sizeof(fh.title) + sizeof(bp->filename)];
	snprintf(buf, sizeof(buf), "%sed '%s' on %s", isedit ? "edit" : "post",
			title, bp->filename);
	report(buf, currentuser.userid);

	snprintf(buf, sizeof(buf), "doc?board=%s", bp->filename);
	http_header();
	refreshto(1, buf);
	printf("</head>\n<body>发表成功,1秒钟后自动转到<a href='%s'>版面</a>\n"
			"</body>\n</html>\n", buf);
	return 0;
}
Esempio n. 22
0
int web_sector(void)
{
	int sid = 0;
	board_t parent = { .id = 0 };
	db_res_t *res = NULL;

	const char *sname = web_get_param("s");
	if (*sname) {
		res = db_query("SELECT id, descr"
				" FROM board_sectors WHERE name = %s", sname);
		if (!res || db_res_rows(res) < 1) {
			db_clear(res);
			return BBS_EINVAL;
		}
	} else {
		const char *pname = web_get_param("board");
		if (*pname)
			get_board(pname, &parent);
		else
			get_board_by_bid(strtol(web_get_param("bid"), NULL, 10), &parent);
		if (!parent.id || !(parent.flag & BOARD_FLAG_DIR)
				|| !has_read_perm(&parent))
			return BBS_ENOBRD;
	}

	xml_header(NULL);
	printf("<bbsboa link='%sdoc' ", get_post_list_type_string());

	if (*sname) {
		char path[HOMELEN];
		sprintf(path, "%s/info/egroup%d/icon.jpg", BBSHOME,
				(int) strtol(sname, NULL, 16));
		if (dashf(path))
			printf(" icon='%s'", path);
		
		const char *utf8_sector = db_get_value(res, 0, 1);
		if (web_request_type(UTF8)) {
			printf(" title='%s'>", utf8_sector);
		} else {
			GBK_BUFFER(sector, BOARD_SECTOR_NAME_CCHARS);
			convert_u2g(utf8_sector, gbk_sector);
			printf(" title='%s'>", gbk_sector);
		}
		sid = db_get_integer(res, 0, 0);
		db_clear(res);
	} else {
		if (web_request_type(UTF8)) {
			printf(" dir= '1' title='%s'>", parent.descr);
		} else {
			GBK_BUFFER(descr, BOARD_DESCR_CCHARS);
			convert_u2g(parent.descr, gbk_descr);
			printf(" dir= '1' title='%s'>", gbk_descr);
		}
	}

	if (sid)
		res = db_query(BOARD_SELECT_QUERY_BASE "WHERE b.sector = %d", sid);
	else
		res = db_query(BOARD_SELECT_QUERY_BASE "WHERE b.parent = %d", parent.id);

	if (res && db_res_rows(res) > 0)
		show_board(res);
	db_clear(res);

	print_session();
	printf("</bbsboa>");
	return 0;
}

int bbsclear_main(void)
{
	if (!session_id())
		return BBS_ELGNREQ;

	board_t board;
	if (!get_board(web_get_param("board"), &board)
			|| !has_read_perm(&board))
		return BBS_ENOBRD;
	session_set_board(board.id);

	const char *start = web_get_param("start");
	brc_init(currentuser.userid, board.name);
	brc_clear_all();
	brc_sync(currentuser.userid);
	char buf[STRLEN];
	snprintf(buf, sizeof(buf), "doc?board=%s&start=%s", board.name, start);
	http_header();
	refreshto(0, buf);
	printf("</head></html>");
	return 0;
}

int bbsnot_main(void)
{
	board_t board;
	if (!get_board(web_get_param("board"), &board)
			|| !has_read_perm(&board))
		return BBS_ENOBRD;

	if (board.flag & BOARD_FLAG_DIR)
		return BBS_EINVAL;
	session_set_board(board.id);

	char fname[HOMELEN];
	snprintf(fname, sizeof(fname), "vote/%s/notes", board.name);
	mmap_t m;
	m.oflag = O_RDONLY;
	if (mmap_open(fname, &m) < 0)
		return BBS_ENOFILE;
	xml_header(NULL);
	printf("<bbsnot brd='%s'>", board.name);
	xml_fputs2((char *) m.ptr, m.size);
	mmap_close(&m);
	print_session();
	printf("</bbsnot>");
	return 0;
}
Esempio n. 23
0
File: http.cpp Progetto: Leonya/xiva
http_header
http_header::connection_keep_alive() {
	return http_header("Connection", "keep-alive");
}
Esempio n. 24
0
File: http.cpp Progetto: Leonya/xiva
http_header
http_header::connection_close() {
	return http_header("Connection", "close");
}
Esempio n. 25
0
File: http.cpp Progetto: Leonya/xiva
http_header
http_header::server() {
	return http_header("Server", XIVA_PACKAGE_NAME "/" XIVA_PACKAGE_VERSION);
}
Esempio n. 26
0
static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, char *read_ptr ) {
  int               numwant, tmp, scanon;
  unsigned short    port = 0;
  char             *write_ptr;
  ssize_t           len;
  struct http_data *cookie = io_getcookie( sock );

  /* This is to hack around stupid clients that send "announce ?info_hash" */
  if( read_ptr[-1] != '?' ) {
    while( ( *read_ptr != '?' ) && ( *read_ptr != '\n' ) ) ++read_ptr;
    if( *read_ptr == '\n' ) HTTPERROR_400_PARAM;
    ++read_ptr;
  }

#ifdef WANT_IP_FROM_PROXY
  if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) {
    ot_ip6 proxied_ip;
    char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" );
    if( fwd && scan_ip6( fwd, proxied_ip ) )
      OT_SETIP( &ws->peer, proxied_ip );
    else
      OT_SETIP( &ws->peer, cookie->ip );
  } else
#endif
  OT_SETIP( &ws->peer, cookie->ip );

  ws->peer_id = NULL;
  ws->hash = NULL;

  OT_SETPORT( &ws->peer, &port );
  OT_PEERFLAG( &ws->peer ) = 0;
  numwant = 50;
  scanon = 1;

  while( scanon ) {
    switch( scan_find_keywords(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM ) ) {
    case -2: scanon = 0; break;   /* TERMINATOR */
    case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */
    case -3: scan_urlencoded_skipvalue( &read_ptr ); break;
    case 1: /* matched "port" */
      len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE );
      if( ( len <= 0 ) || scan_fixed_int( write_ptr, len, &tmp ) || ( tmp > 0xffff ) ) HTTPERROR_400_PARAM;
      port = htons( tmp ); OT_SETPORT( &ws->peer, &port );
      break;
    case 2: /* matched "left" */
      if( ( len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ) ) <= 0 ) HTTPERROR_400_PARAM;
      if( scan_fixed_int( write_ptr, len, &tmp ) ) tmp = 0;
      if( !tmp ) OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_SEEDING;
      break;
    case 3: /* matched "event" */
      switch( scan_find_keywords( keywords_announce_event, &read_ptr, SCAN_SEARCHPATH_VALUE ) ) {
        case -1: HTTPERROR_400_PARAM;
        case  1: /* matched "completed" */
          OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_COMPLETED;
          break;
        case  2: /* matched "stopped" */
          OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_STOPPED;
          break;
        default:
          break;
      }
      break;
    case 4: /* matched "numwant" */
      len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE );
      if( ( len <= 0 ) || scan_fixed_int( write_ptr, len, &numwant ) ) HTTPERROR_400_PARAM;
      if( numwant < 0 ) numwant = 50;
      if( numwant > 200 ) numwant = 200;
      break;
    case 5: /* matched "compact" */
      len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE );
      if( ( len <= 0 ) || scan_fixed_int( write_ptr, len, &tmp ) ) HTTPERROR_400_PARAM;
      if( !tmp ) HTTPERROR_400_COMPACT;
      break;
    case 6: /* matched "info_hash" */
      if( ws->hash ) HTTPERROR_400_DOUBLEHASH;
      /* ignore this, when we have less than 20 bytes */
      if( scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM;
        ws->hash = (ot_hash*)write_ptr;
      break;
#ifdef WANT_IP_FROM_QUERY_STRING
    case  7: /* matched "ip" */
      {
        char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply+16;
        len = scan_urlencoded_query( &read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE );
        tmp_buf2[len] = 0;
        if( ( len <= 0 ) || !scan_ip6( tmp_buf2, tmp_buf1 ) ) HTTPERROR_400_PARAM;
        OT_SETIP( &ws->peer, tmp_buf1 );
      }
      break;
#endif
#ifdef WANT_FULLLOG_NETWORKS
      case 8: /* matched "lognet" */
      {
        //if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) {
          char *tmp_buf = ws->reply;
          ot_net net;
          signed short parsed, bits;

          len = scan_urlencoded_query( &read_ptr, tmp_buf, SCAN_SEARCHPATH_VALUE );
          tmp_buf[len] = 0;
          if( len <= 0 ) HTTPERROR_400_PARAM;
          if( *tmp_buf == '-' ) {
            loglist_reset( );
            return ws->reply_size = sprintf( ws->reply, "Successfully removed.\n" );
          }
          parsed = scan_ip6( tmp_buf, net.address );
          if( !parsed ) HTTPERROR_400_PARAM;
          if( tmp_buf[parsed++] != '/' )
            bits = 128;
          else {
            parsed = scan_short( tmp_buf + parsed, &bits );
            if( !parsed ) HTTPERROR_400_PARAM; 
            if( ip6_isv4mapped( net.address ) )
              bits += 96;
          }
          net.bits = bits;
          loglist_add_network( &net );
          return ws->reply_size = sprintf( ws->reply, "Successfully added.\n" );
        //}
      }
#endif
        break;
      case 9: /* matched "peer_id" */
        /* ignore this, when we have less than 20 bytes */
        if( scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM;
        ws->peer_id = write_ptr;
        break;
    }
  }

#ifdef WANT_LOG_NUMWANT
  numwants[numwant]++;
#endif

  /* XXX DEBUG
  stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ws->reply );
  */

  /* Scanned whole query string */
  if( !ws->hash )
    return ws->reply_size = sprintf( ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" );

  if( OT_PEERFLAG( &ws->peer ) & PEER_FLAG_STOPPED )
    ws->reply_size = remove_peer_from_torrent( FLAG_TCP, ws );
  else
    ws->reply_size = add_peer_to_torrent_and_return_peers( FLAG_TCP, ws, numwant );

  stats_issue_event( EVENT_ANNOUNCE, FLAG_TCP, ws->reply_size);
  return ws->reply_size;
}