⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpprsbin.c

📁 PGP—Pretty Good Privacy
💻 C
📖 第 1 页 / 共 5 页
字号:
					myself->write = DoWrite;
				}
			}
			break;
		}
		break;
	default:
		error = kPGPError_BadParams;
	}

	if (error) {
		/* Get rid of partial pipelines (if any) */
		if (IsNull(ctx->end)  ||  IsNull(*(ctx->end)))
			ctx->end = &oldhead;
		parsePipelineTeardown (ctx);
	} else {
		/* Splice the new into the old */
		*(ctx->end) = oldhead;
		ctx->needcallback--;
	}

	return error;
}

static size_t
parseLiteral (PGPPipeline *myself, PGPByte const *buf, size_t size,
		PGPError *error)
{
	PrsBinContext *ctx;
	size_t len;
	size_t size0 = size;
	PGPByte const *p;

	pgpAssert (myself);
	pgpAssert (myself->magic == PARSERMAGIC);
	pgpAssert (error);

	ctx = (PrsBinContext *)myself->priv;
	pgpAssert (ctx);
	pgpAssert (ctx->tail);
	pgpAssert (!size || !ctx->eof);

	*error = kPGPError_NoErr;

	switch (ctx->state) {
	case 0:
	case 10:	/* flags oldliteral, where length doesn't include prefix */
				/* may also be pgpHeader.c packet, type 'P' */
		/* Parse header; needed before callbacks are allowed */
		len = inputMerge(&ctx->input, buf, size, 2, error);
		buf += len;
		size -= len;
		if (*error || !size)
			break;
		/* Size is non-zero but we haven't got desired?  EOP */
		if (inputMerged(&ctx->input) < 2) {
			pgpAssert(inputFinished(&ctx->input.head));
			*error = ctx->tail->annotate(ctx->tail, myself,
			                             PGPANN_PACKET_SHORT,
						     0, 0);
			if (*error)
				break;
			myself->write = nextScope;
			size -= nextScope (myself, buf, size, error);
			break;
		}
		p = inputMergedPtr(&ctx->input);
		/* Deal with "oldliteral" packets specially */
		if (ctx->state == 10) {
			if (p[0] == 'P') {
				/* Special PGP 3 header */
				myself->write = DoSkip;
				size -= DoSkip (myself, buf, size, error);
				break;
			}
			/* Else old-style packets; some PGPcompatible program does these */
			/*
			 * That program uses "literal" length conventions, not
			 * "oldliteral", so don't do this:
			 *
			 * if (ctx->input.head.pktlen != ~0UL) {
			 *   ctx->input.head.pktlen += 6 + p[1];
			 * }
			 */
			ctx->state = 0;
		}
		/* Get the name and timestamp fields */
		len = inputMerge(&ctx->input, buf, size, 6+p[1], error);
		buf += len;
		size -= len;
		/* Size may be zero here if output file is zero length */
		if (*error)
			break;
		if (inputMerged(&ctx->input) < (unsigned)6+p[1]) {
			if( size == 0 )
				break;
			/* Size is non-zero but we haven't got desired?  EOP */
			pgpAssert(inputFinished(&ctx->input.head));
			*error = ctx->tail->annotate(ctx->tail, myself,
			                             PGPANN_PACKET_SHORT,
						     0, 0);
			if (*error)
				break;
			myself->write = nextScope;
			size -= nextScope (myself, buf, size, error);
			break;
		}

		ctx->subtype = p[0];
		ctx->needcallback = 1;
		ctx->end_scope = PGPANN_LITERAL_END;
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_LITERAL_BEGIN, 0, 0);
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 1:
		p = inputMergedPtr(&ctx->input);
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_LITERAL_NAME,
		                              p+2, (size_t)p[1]);
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 2:
		/* Parse 4-byte timestamp */
		p = inputMergedPtr(&ctx->input);
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_LITERAL_TIMESTAMP,
		                              p+2+p[1], 4);
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 3:
		p = inputMergedPtr(&ctx->input);
		if (ctx->subtype == PGP_LITERAL_TEXT) {
			/* See if looks like PGP message, set as RECURSE type */
			len = inputMerge(&ctx->input, buf, size,
							 6+p[1]+sizeof(pgp_message_begin)-1, error);
			buf += len;
			size -= len;
			if (*error)
				break;
			if (inputMerged(&ctx->input) < 6+p[1]+sizeof(pgp_message_begin)-1){
				/* Get more data if not enough to check */
				if (!inputFinished(&ctx->input.head))
					break;
			} else {
				if (memcmp (p+p[1]+6, pgp_message_begin,
							sizeof(pgp_message_begin)-1) == 0) {
					/* Looks like PGP message, set type as RECURSE */
					ctx->subtype = PGP_LITERAL_RECURSE;
				}
			}
			/* Advance buffer past initial data */
			ctx->input.bufptr += p[1]+6;
			ctx->nopurge = TRUE;
		}
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_LITERAL_TYPE, &ctx->subtype, 1);
		if (*error)
			break;
		
		ctx->state++;
		/* FALLTHROUGH */
	case 4:
		if (ctx->needcallback) {
			*error = ctx->tail->annotate (ctx->tail, myself,
			                              PGPANN_COMMIT, 0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		/* FALLTHROUGH */
	case 5:
		if (ctx->needcallback) {
			*error = ProcessCallback (myself,
						  PGPANN_PARSER_PROCESS,
						  0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		/* Zero length files don't produce output, do an extra write here */
		if( myself->write == DoWrite ) {
			ctx->tail->write( ctx->tail, buf, 0, error );
		}
		if (*error)
			break;
		/* Write remaining chars from buf */
		size -= myself->write(myself, buf, size, error);
		break;
	default:
		pgpAssert (0);	/* I should never get here */
	}

	return size0-size;
}

static size_t
parseCipher (PGPPipeline *myself, PGPByte const *buf, size_t size,
	     PGPError *error)
{
	PrsBinContext *ctx;
	size_t written = 0;

	pgpAssert (myself);
	pgpAssert (myself->magic == PARSERMAGIC);
	pgpAssert (error);

	ctx = (PrsBinContext *)myself->priv;
	pgpAssert (ctx);
	pgpAssert (ctx->tail);
	pgpAssert (!size || !ctx->eof);

	*error = kPGPError_NoErr;

	switch (ctx->state) {
	case 0:
		/* Parse header; needed before callbacks are allowed */
		written = inputMerge(&ctx->input, buf, size, MAXIVLEN+2, error);
		buf += written;
		size -= written;
		if (*error || !size)
			break;
		/* Size is non-zero but we haven't got desired?  EOP */
		if (inputMerged(&ctx->input) < MAXIVLEN+2) {
			pgpAssert(inputFinished(&ctx->input.head));
			*error = ctx->tail->annotate(ctx->tail, myself,
			                             PGPANN_PACKET_SHORT,
						     0, 0);
			if (*error)
				break;
			myself->write = nextScope;
			size -= nextScope (myself, buf, size, error);
			break;
		}

		ctx->needcallback = 1;

		/*
		 * If we're already in an encrypted scope (we've already
		 * sent some ESKs to the user), don't bother sending another
		 * one.
		 */
		if (ctx->end_scope) {	/* Scope alreay open? */
			ctx->state = 2;
			goto got_esk;
		}
		/* No ESKs seen yet - open the scope */
		ctx->end_scope = PGPANN_CIPHER_END;
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_CIPHER_BEGIN, 0, 0);
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 1:
		/* No ESKs seen yet - dummy one up */
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_SKCIPHER_ESK, 0, 0);
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 2:
	got_esk:
		/* Okay, do a commit */
		if (ctx->needcallback) {
			*error = ctx->tail->annotate (ctx->tail, myself,
			                              PGPANN_COMMIT, 0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		/* FALLTHROUGH */
	case 3:
		if (ctx->needcallback) {
			*error = ProcessCallback (myself,
						  PGPANN_PARSER_PASSTHROUGH,
						  0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		written += myself->write(myself, buf, size, error);
		break;
	default:
		pgpAssert (0);
	}

	return written;
}

static size_t
parseCompressed (PGPPipeline *myself, PGPByte const *buf, size_t size,
		 PGPError *error)
{
	PrsBinContext *ctx;
	size_t written = 0;

	pgpAssert (myself);
	pgpAssert (myself->magic == PARSERMAGIC);
	pgpAssert (error);

	ctx = (PrsBinContext *)myself->priv;
	pgpAssert (ctx);
	pgpAssert (ctx->tail);
	pgpAssert (!size || !ctx->eof);

	*error = kPGPError_NoErr;

	switch (ctx->state) {
	case 0:
		/* Make sure we have the compression type */
		written = inputMerge(&ctx->input, buf, size, 1, error);
		buf += written;
		size -= written;
		if (*error || !size)
			break;
		/* Size is non-zero but we haven't got desired?  EOP */
		if (inputMerged(&ctx->input) < 1) {
			pgpAssert(inputFinished(&ctx->input.head));
			*error = ctx->tail->annotate(ctx->tail, myself,
			                             PGPANN_PACKET_SHORT,
						     0, 0);
			if (*error)
				break;
			myself->write = nextScope;
			size -= nextScope (myself, buf, size, error);
			break;
		}

		ctx->needcallback = 1;
		ctx->end_scope = PGPANN_COMPRESSED_END;
		*error = ctx->tail->annotate (ctx->tail, myself,
		                              PGPANN_COMPRESSED_BEGIN,
		                              inputMergedPtr(&ctx->input), 1);
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 1:
		if (ctx->needcallback) {
			*error = ctx->tail->annotate (ctx->tail, myself,
			                              PGPANN_COMMIT, 0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		/* FALLTHROUGH */
	case 2:
		if (ctx->needcallback) {
			*error = ProcessCallback (myself,
						  PGPANN_PARSER_RECURSE,
						  0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		written += myself->write(myself, buf, size, error);
		break;
	default:
		pgpAssert (0);
	}

	return written;
}

/*
 * Parse a general headerless packet.  Unknown packets, comment packets
 * and, in fact, things that aren't packets at all!
 */
static size_t
parseUnknown (PGPPipeline *myself, PGPByte const *buf, size_t size,
	PGPError *error)
{
	PrsBinContext *ctx;
	size_t written = 0;
	PGPByte b;
	int begintype;

	pgpAssert (myself);
	pgpAssert (myself->magic == PARSERMAGIC);
	pgpAssert (error);

	ctx = (PrsBinContext *)myself->priv;
	pgpAssert (ctx);
	pgpAssert (ctx->tail);
	pgpAssert (!size || !ctx->eof);

	*error = kPGPError_NoErr;

	switch (ctx->state) {
	case 0:
		/*
		 * As a convenience, we merge a leading prefix of the packet
		 * for identification purposes.
		 */
		written = inputMerge(&ctx->input, buf, size, 256, error);
		buf += written;
		size -= written;
		if (*error)
			return written;
		if (inputMerged(&ctx->input) < 256 &&
		    !inputFinished(&ctx->input.head))
		{
			pgpAssert(!size);
			return written;
		}

		/*
		 * We use this one function to provide different
		 * annotations for non-packets, comment packets, and
		 * unknown packets.  Figure out the right one to use.
		 */
		b = ctx->input.buffer[0];
		if (!IS_OLD_PKTBYTE(b) && !IS_NEW_PKTBYTE(b)) {
			begintype = PGPANN_NONPACKET_BEGIN;
			ctx->end_scope = PGPANN_NONPACKET_END;
		} else if (PKTBYTE_TYPE (b) == PKTBYTE_COMMENT) {
			begintype = PGPANN_COMMENT_BEGIN;
			ctx->end_scope = PGPANN_COMMENT_END;
		} else {
			begintype = PGPANN_UNKNOWN_BEGIN;
			ctx->end_scope = PGPANN_UNKNOWN_END;
		}
		
		ctx->needcallback = 1;
		*error = ctx->tail->annotate (ctx->tail, myself, begintype,
		                              inputMergedPtr(&ctx->input),
		                              inputMerged(&ctx->input));
		if (*error)
			break;

		ctx->state++;
		/* FALLTHROUGH */
	case 1:
		if (ctx->needcallback) {
			*error = ctx->tail->annotate (ctx->tail, myself,
			                              PGPANN_COMMIT, 0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		/* FALLTHROUGH */
	case 2:
		if (ctx->needcallback) {
			*error = ProcessCallback (myself, PGPANN_PARSER_EATIT,
						  0, 0);
			if (*error)
				break;
		}
		ctx->state++;
		return written + myself->write(myself, buf, size, error);
		/* NOTREACHED */
	default:
		pgpAssert (0);
	}

	return written;
}

/*
 * This is called for most all key-type packets.  Keys are just output
 * within a key annotation scope.  There is no callback, since no
 * processing is done.
 */
static size_t

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -