Beispiel #1
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;
	}
}
Beispiel #2
0
/* Serve a single HTTP request */
static void
http_serve(FILE *in, FILE *out, const char *mime_type)
{
	char line[10000], method[10000], path[10000], protocol[10000];
	char *file;
	size_t len;
	struct stat sb;
	struct query *q;

	if (fgets(line, sizeof(line), in) == (char *) 0) {
		send_error(out, 400, "Bad Request", (char *) 0,
		    "No request found.");
		return;
	}
	if (sscanf(line, "%[^ ] %[^ ] %[^ ]", method, path, protocol) != 3) {
		send_error(out, 400, "Bad Request", (char *) 0,
		    "Can't parse request.");
		return;
	}
	while (fgets(line, sizeof(line), in) != (char *) 0) {
		if (strcmp(line, "\n") == 0 || strcmp(line, "\r\n") == 0)
			break;
	}
	if (strcasecmp(method, "get") != 0) {
		send_error(out, 501, "Not Implemented", (char *) 0,
		    "That method is not implemented.");
		return;
	}
	if (path[0] != '/') {
		send_error(out, 400, "Bad Request", (char *) 0, "Bad filename.");
		return;
	}
	file = &(path[1]);
	strdecode(file, file);

	if (strcmp(file, ".server?quit") == 0) {
		send_error(out, 200, "OK", (char *) 0,
		    "Quitting.");
		exit(0);
	}

	len = strlen(file);

	/* Guard against attempts to move outside our directory */
	if (file[0] == '/' || strcmp(file, "..") == 0
	    || strncmp(file, "../", 3) == 0
	    || strstr(file, "/../") != (char *) 0
	    || strcmp(&(file[len - 3]), "/..") == 0) {
		send_error(out, 400, "Bad Request", (char *) 0,
		    "Illegal filename.");
		return;
	}

	/* User-specified query name space */
	for (q = query_list; q; q = q->next) {
		int v0, v1, v2, v3, v4, v5, v6, v7, v8, v9;
		char cmd[11000];

		*cmd = 0;
		if (q->narg == 0 && strcmp(file, q->query) == 0)
			strncpy(cmd, q->cmd, sizeof(cmd));
		else if (q->narg && sscanf(file, q->query, &v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9) == q->narg)
			snprintf(cmd, sizeof(cmd), q->cmd, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
		if (*cmd) {
			int ich;
			FILE *fp;

			fp = popen(cmd, "r");
			if (fp == NULL) {
				send_error(out, 502, "Bad Gateway", NULL, "Error in executing command.");
				return;
			}
			send_headers(out, 200, "Ok", NULL, mime_type, -1,
				time(NULL));
			while ((ich = getc(fp)) != EOF)
				putc(ich, out);
			fclose(fp);
			return;
		}
	}

	/* File system name space */
	if (stat(file, &sb) < 0) {
		send_error(out, 404, "Not Found", NULL, "File not found.");
		return;
	}
	if (S_ISSOCK(sb.st_mode)) {
		/* Value store */
		send_headers(out, 200, "Ok", NULL, mime_type,
		    -1, (time_t)-1);
		(void)fflush(out);
		sgsh_send_command(file, read_cmd, true, false, fileno(out));
	} else if (S_ISREG(sb.st_mode)) {
		/* Regular file */
		int ich;
		FILE *fp;

		fp = fopen(file, "r");
		if (fp == NULL) {
			send_error(out, 403, "Forbidden", NULL, "File is protected.");
			return;
		}
		send_headers(out, 200, "Ok", NULL, get_mime_type(file),
			sb.st_size, sb.st_mtime);
		while ((ich = getc(fp)) != EOF)
			putc(ich, out);
		fclose(fp);
	} else {
		send_error(out, 403, "Forbidden", (char *) 0,
		    "File is not a regular file or a Unix domain socket.");
	}
}