main.c
/*
 * Process responsible for parsing and validating content.
 * All this process does is wait to be told about a file to parse, then
 * it parses it and makes sure that the data being returned is fully
 * validated and verified.
 * The process will exit cleanly only when fd is closed.
 */
Process responsible for parsing and validating content.
All this process does is wait to be told about a file to parse, then
it parses it and makes sure that the data being returned is fully
validated and verified.
The process will exit cleanly only when fd is closed.
Process responsible for parsing and validating content . All this process does is wait to be told about a file to parse then it parses it and makes sure that the data being returned is fully validated and verified . The process will exit cleanly only when fd is closed .
static void
proc_parser(int fd, int force)
{
	struct tal	*tal;
	struct cert	*cert;
	struct mft	*mft;
	struct roa	*roa;
	struct entity	*entp;
	struct entityq	 q;
	int		 c, rc = 1;
	struct pollfd	 pfd;
	char		*b = NULL;
	size_t		 bsz = 0, bmax = 0, bpos = 0;
	ssize_t		 ssz;
	X509_STORE	*store;
	X509_STORE_CTX	*ctx;
	struct auth_tree auths = RB_INITIALIZER(&auths);
	struct crl_tree	 crlt = RB_INITIALIZER(&crlt);
	ERR_load_crypto_strings();
	OpenSSL_add_all_ciphers();
	OpenSSL_add_all_digests();
	if ((store = X509_STORE_new()) == NULL)
		cryptoerrx("X509_STORE_new");
	if ((ctx = X509_STORE_CTX_new()) == NULL)
		cryptoerrx("X509_STORE_CTX_new");
	TAILQ_INIT(&q);
	pfd.fd = fd;
	pfd.events = POLLIN;
	io_socket_nonblocking(pfd.fd);
	for (;;) {
		if (poll(&pfd, 1, INFTIM) == -1)
			err(1, "poll");
		if ((pfd.revents & (POLLERR|POLLNVAL)))
			errx(1, "poll: bad descriptor");
		if ((pfd.revents & POLLHUP))
			break;
		if ((pfd.revents & POLLIN)) {
			io_socket_blocking(fd);
			entp = calloc(1, sizeof(struct entity));
			if (entp == NULL)
				err(1, NULL);
			entity_read_req(fd, entp);
			TAILQ_INSERT_TAIL(&q, entp, entries);
			pfd.events |= POLLOUT;
			io_socket_nonblocking(fd);
		}
		if (!(pfd.revents & POLLOUT))
			continue;
		if (bsz) {
			assert(bpos < bmax);
			if ((ssz = write(fd, b + bpos, bsz)) == -1)
				err(1, "write");
			bpos += ssz;
			bsz -= ssz;
			if (bsz)
				continue;
			bpos = bsz = 0;
		}
		if (TAILQ_EMPTY(&q)) {
			pfd.events &= ~POLLOUT;
			continue;
		}
		entp = TAILQ_FIRST(&q);
		assert(entp != NULL);
		entity_buffer_resp(&b, &bsz, &bmax, entp);
		switch (entp->type) {
		case RTYPE_TAL:
			assert(!entp->has_dgst);
			if ((tal = tal_parse(entp->uri, entp->descr)) == NULL)
				goto out;
			tal_buffer(&b, &bsz, &bmax, tal);
			tal_free(tal);
			break;
		case RTYPE_CER:
			cert = proc_parser_cert(entp, store, ctx,
			    &auths, &crlt);
			c = (cert != NULL);
			io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
			if (cert != NULL)
				cert_buffer(&b, &bsz, &bmax, cert);
			break;
		case RTYPE_MFT:
			mft = proc_parser_mft(entp, force,
			    store, ctx, &auths, &crlt);
			c = (mft != NULL);
			io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
			if (mft != NULL)
				mft_buffer(&b, &bsz, &bmax, mft);
			mft_free(mft);
			break;
		case RTYPE_CRL:
			proc_parser_crl(entp, store, ctx, &crlt);
			break;
		case RTYPE_ROA:
			assert(entp->has_dgst);
			roa = proc_parser_roa(entp, store, ctx, &auths, &crlt);
			c = (roa != NULL);
			io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int));
			if (roa != NULL)
				roa_buffer(&b, &bsz, &bmax, roa);
			roa_free(roa);
			break;
		default:
			abort();
		}
		TAILQ_REMOVE(&q, entp, entries);
		entity_free(entp);
	}
	rc = 0;
out:
	while ((entp = TAILQ_FIRST(&q)) != NULL) {
		TAILQ_REMOVE(&q, entp, entries);
		entity_free(entp);
	}
	X509_STORE_CTX_free(ctx);
	X509_STORE_free(store);
	free(b);
	exit(rc);
}
static void proc_parser ( int fd , int force ) { struct tal * tal ; struct cert * cert ; struct mft * mft ; struct roa * roa ; struct entity * entp ; struct entityq q ; int c , rc = 1 ; struct pollfd pfd ; char * b = NULL ; size_t bsz = 0 , bmax = 0 , bpos = 0 ; ssize_t ssz ; X509_STORE * store ; X509_STORE_CTX * ctx ; struct auth_tree auths = RB_INITIALIZER ( & auths ) ; struct crl_tree crlt = RB_INITIALIZER ( & crlt ) ; ERR_load_crypto_strings ( ) ; OpenSSL_add_all_ciphers ( ) ; OpenSSL_add_all_digests ( ) ; if ( ( store = X509_STORE_new ( ) ) == NULL ) cryptoerrx ( " " ) ; if ( ( ctx = X509_STORE_CTX_new ( ) ) == NULL ) cryptoerrx ( " " ) ; TAILQ_INIT ( & q ) ; pfd . fd = fd ; pfd . events = POLLIN ; io_socket_nonblocking ( pfd . fd ) ; for ( ; ; ) { if ( poll ( & pfd , 1 , INFTIM ) == -1 ) err ( 1 , " " ) ; if ( ( pfd . revents & ( POLLERR | POLLNVAL ) ) ) errx ( 1 , " " ) ; if ( ( pfd . revents & POLLHUP ) ) break ; if ( ( pfd . revents & POLLIN ) ) { io_socket_blocking ( fd ) ; entp = calloc ( 1 , sizeof ( struct entity ) ) ; if ( entp == NULL ) err ( 1 , NULL ) ; entity_read_req ( fd , entp ) ; TAILQ_INSERT_TAIL ( & q , entp , entries ) ; pfd . events |= POLLOUT ; io_socket_nonblocking ( fd ) ; } if ( ! ( pfd . revents & POLLOUT ) ) continue ; if ( bsz ) { assert ( bpos < bmax ) ; if ( ( ssz = write ( fd , b + bpos , bsz ) ) == -1 ) err ( 1 , " " ) ; bpos += ssz ; bsz -= ssz ; if ( bsz ) continue ; bpos = bsz = 0 ; } if ( TAILQ_EMPTY ( & q ) ) { pfd . events &= ~ POLLOUT ; continue ; } entp = TAILQ_FIRST ( & q ) ; assert ( entp != NULL ) ; entity_buffer_resp ( & b , & bsz , & bmax , entp ) ; switch ( entp -> type ) { case RTYPE_TAL : assert ( ! entp -> has_dgst ) ; if ( ( tal = tal_parse ( entp -> uri , entp -> descr ) ) == NULL ) goto out ; tal_buffer ( & b , & bsz , & bmax , tal ) ; tal_free ( tal ) ; break ; case RTYPE_CER : cert = proc_parser_cert ( entp , store , ctx , & auths , & crlt ) ; c = ( cert != NULL ) ; io_simple_buffer ( & b , & bsz , & bmax , & c , sizeof ( int ) ) ; if ( cert != NULL ) cert_buffer ( & b , & bsz , & bmax , cert ) ; break ; case RTYPE_MFT : mft = proc_parser_mft ( entp , force , store , ctx , & auths , & crlt ) ; c = ( mft != NULL ) ; io_simple_buffer ( & b , & bsz , & bmax , & c , sizeof ( int ) ) ; if ( mft != NULL ) mft_buffer ( & b , & bsz , & bmax , mft ) ; mft_free ( mft ) ; break ; case RTYPE_CRL : proc_parser_crl ( entp , store , ctx , & crlt ) ; break ; case RTYPE_ROA : assert ( entp -> has_dgst ) ; roa = proc_parser_roa ( entp , store , ctx , & auths , & crlt ) ; c = ( roa != NULL ) ; io_simple_buffer ( & b , & bsz , & bmax , & c , sizeof ( int ) ) ; if ( roa != NULL ) roa_buffer ( & b , & bsz , & bmax , roa ) ; roa_free ( roa ) ; break ; default : abort ( ) ; } TAILQ_REMOVE ( & q , entp , entries ) ; entity_free ( entp ) ; } rc = 0 ; out : while ( ( entp = TAILQ_FIRST ( & q ) ) != NULL ) { TAILQ_REMOVE ( & q , entp , entries ) ; entity_free ( entp ) ; } X509_STORE_CTX_free ( ctx ) ; X509_STORE_free ( store ) ; free ( b ) ; exit ( rc ) ; }
Process responsible for parsing and validating content.
Process responsible for parsing and validating content .
/* If the parent closes, return immediately. */ /*
		 * Start with read events.
		 * This means that the parent process is sending us
		 * something we need to parse.
		 * We don't actually parse it til we have space in our
		 * outgoing buffer for responding, though.
		 */ /*
		 * If we have a write buffer, then continue trying to
		 * push it all out.
		 * When it's all pushed out, reset it and get ready to
		 * continue sucking down more data.
		 */ /*
		 * If there's nothing to parse, then stop waiting for
		 * the write signal.
		 */ /*
			 * The parsed certificate data "cert" is now
			 * managed in the "auths" table, so don't free
			 * it here (see the loop after "out").
			 */ /* XXX free auths and crl tree */