📄 pgparmor.c
字号:
}
}
context->sizevalid = 1;
if (bytes)
return kPGPError_NoErr; /* dont handle any more non-zero sizeAdvises */
/* This is the end */
context->sizevalid = 2;
/* Clear out the clearsign buffer, if we have it. */
if (context->clearsign && context->linebuf) {
pgpFifoWrite (context->fd, context->header, context->input,
context->linebuf);
context->linebuf = 0;
}
/*
* If clearsign input ended with '\r', will be hashed with '\r\n' but
* the output file will be missing the '\n'. Add it here.
*/
if (context->clearsign && context->state==2) {
pgpFifoWrite (context->fd,
context->header, (const unsigned char *) "\n",
1);
context->state = 0;
}
error = armorFlushFifo (myself);
if (error)
return error;
if (!context->didheader && !context->clearsign)
armorMakeHeader (context);
error = DoFlush (myself);
if (error)
return error;
if (!context->clearsign) {
armorMakeFooter (context);
/* Set clearsign so we don't emit another CRC */
context->clearsign = 1;
error = DoFlush (myself);
if (error)
return error;
}
if (context->tail)
error = context->tail->sizeAdvise (context->tail, bytes);
return error;
}
static PGPError
Teardown (PGPPipeline *myself)
{
ArmorContext * context;
PGPContextRef cdkContext;
pgpAssertAddrValid( myself, PGPPipeline );
cdkContext = myself->cdkContext;
pgpAssert (myself);
pgpAssert (myself->magic == ARMORMAGIC);
context = (ArmorContext *)myself->priv;
pgpAssert (context);
if (context->tail)
context->tail->teardown (context->tail);
pgpFifoDestroy (context->fd, context->fifo);
pgpFifoDestroy (context->fd, context->header);
if (context->messageid)
{
pgpContextMemFree( cdkContext, context->messageid);
}
pgpClearMemory ( context, sizeof (*context) );
pgpContextMemFree( cdkContext, context);
return( kPGPError_NoErr );
}
#define ATYPE_NORMAL 0
#define ATYPE_CLEARSIG 10
#define ATYPE_SEPSIG 20
#define ATYPE_SEPSIGMSG 21
#define ATYPE_MIMESIG 30
#define ATYPE_MIMEENC 40
#define ATYPE_MIMESEPSIG 50
static PGPPipeline **
armorDoCreate (
PGPContextRef cdkContext,
PGPPipeline ** head,
ArmorContext ** pcontext,
PGPEnv const * env,
PgpVersion version,
PGPFifoDesc const * fd,
PGPRandomContext const *rc,
unsigned long armorlines,
int armortype,
PGPByte const * hashlist,
unsigned hashlen)
{
PGPPipeline *mod;
ArmorContext *context;
PGPFifoContext *fifo;
PGPFifoContext *header;
if (!head)
return NULL;
pgpAssert (fd);
context = (ArmorContext *)pgpContextMemAlloc( cdkContext,
sizeof (*context), kPGPMemoryMgrFlags_Clear );
if ( IsNull( context ) )
return NULL;
mod = &context->pipe;
if( IsntNull( pcontext ) )
*pcontext = context;
fifo = pgpFifoCreate ( cdkContext, fd);
if (!fifo) {
pgpContextMemFree( cdkContext, context);
return NULL;
}
header = pgpFifoCreate (cdkContext, fd);
if (!header) {
pgpFifoDestroy (fd, fifo);
pgpContextMemFree( cdkContext, context);
return NULL;
}
mod->magic = ARMORMAGIC;
mod->write = Write;
mod->flush = Flush;
mod->sizeAdvise = SizeAdvise;
mod->annotate = Annotate;
mod->teardown = Teardown;
mod->name = "ASCII Armor Write Module";
mod->priv = context;
mod->cdkContext = cdkContext;
context->cdkContext = cdkContext;
context->outptr = context->output;
context->armorlines = armorlines;
context->crc = CRC_INIT;
context->fd = fd;
context->fifo = fifo;
context->header = header;
context->version = version;
context->comment = pgpenvGetCString (env, PGPENV_COMMENT, NULL );
context->versionString = pgpenvGetCString( env,
PGPENV_VERSION_STRING, NULL );
/* Will need to create a message id; now done deterministically later */
if (rc) {
context->needmessageid = TRUE;
}
if (armortype == ATYPE_CLEARSIG) {
#define CLRSIGN "-----BEGIN PGP SIGNED MESSAGE-----"
int dohash=0;
PGPHashVTBL const *hash;
pgpFifoWrite (fd, header, (PGPByte const *)CLRSIGN,
strlen (CLRSIGN));
context->clearsign = 1;
context->armorlines = 0;
/*
* Now deal with multiple hash types. If we don't specify
* the hash type, or the only hash used is MD5, then ignore
* the Hash header. Otherwise, we should print the out
*/
if (!hashlen || (hashlen == 1 && *hashlist == kPGPHashAlgorithm_MD5))
goto clearsig_end;
pgpFifoWrite (fd, header, (PGPByte const *)"\nHash: ", 7);
while (hashlen--) {
hash = pgpHashByNumber ( (PGPHashAlgorithm) (*hashlist++) );
if (hash) {
if (dohash)
pgpFifoWrite (fd, header,
(PGPByte const *)", ", 2);
pgpFifoWrite (fd, header,
(PGPByte const *)hash->name,
strlen (hash->name));
dohash = 1;
}
}
clearsig_end:
pgpFifoWrite (fd, header, (PGPByte const *)"\n\n", 2);
context->didheader = TRUE; /* No need for header here */
} else if (armortype == ATYPE_MIMESIG) {
/* pgpFifoWrite (fd, header, (PGPByte const *)MIMETOPHDR, */
/* strlen(MIMETOPHDR));*/
context->clearsign = 1;
context->armorlines = 0;
context->pgpmime = PGPMIMESIG;
} else if (armortype == ATYPE_SEPSIG) {
context->blocktype = "SIGNATURE";
} else if (armortype == ATYPE_SEPSIGMSG) {
context->blocktype = "MESSAGE";
} else if (armortype == ATYPE_MIMESEPSIG) {
context->blocktype = "MESSAGE";
context->pgpmime = PGPMIMESIG;
context->armorlines = 0;
} else if (armortype == ATYPE_MIMEENC) {
context->pgpmime = PGPMIMEENC;
context->armorlines = 0;
context->pgpmimeversionline =
pgpenvGetInt( env, PGPENV_PGPMIMEVERSIONLINE, NULL, NULL );
}
context->tail = *head;
*head = mod;
return &context->tail;
}
PGPPipeline **
pgpArmorWriteCreate (
PGPContextRef cdkContext,
PGPPipeline **head,
PGPEnv const *env,
PGPFifoDesc const *fd,
PGPRandomContext const *rc,
PgpVersion version,
PGPByte armortype)
{
int type = 0;
unsigned long armorlines;
PGPError error;
if (!head)
return NULL;
if (armortype == PGP_ARMOR_NORMAL) {
if (pgpenvGetInt (env, PGPENV_PGPMIME, NULL, &error)) {
type = ATYPE_MIMEENC;
rc = NULL; /* prevents messageid appearing */
} else {
type = ATYPE_NORMAL;
}
} else if (armortype == PGP_ARMOR_SEPSIG) {
type = ATYPE_SEPSIG;
} else if (armortype == PGP_ARMOR_SEPSIGMSG) {
type = ATYPE_SEPSIGMSG;
} else {
return NULL;
}
armorlines = pgpenvGetInt (env, PGPENV_ARMORLINES, NULL, NULL);
return (armorDoCreate ( cdkContext,
head, NULL, env, version, fd, rc, armorlines, type, NULL, 0));
}
PGPPipeline **
pgpArmorWriteCreateClearsig (
PGPPipeline **texthead,
PGPPipeline **signhead,
PGPEnv const *env,
PGPFifoDesc const *fd,
PgpVersion version, PGPByte *hashlist,
unsigned hashlen)
{
PGPPipeline *txthead = NULL, *sighead = NULL;
PGPPipeline **joinhead, **sigtail, **tail;
ArmorContext *context;
PGPContextRef cdkContext = pgpenvGetContext( env );
if (!texthead || !signhead)
return NULL;
joinhead = armorDoCreate ( cdkContext,
&txthead, NULL, env, version, fd, NULL, 0,
ATYPE_CLEARSIG, hashlist, hashlen);
if (!joinhead)
return NULL;
tail = pgpJoinCreate (cdkContext, joinhead, fd);
if (!tail) {
txthead->teardown (txthead);
return NULL;
}
sigtail = armorDoCreate ( cdkContext,
&sighead, NULL, env, version, fd, NULL, 0, ATYPE_SEPSIG, NULL, 0);
if (!sigtail) {
txthead->teardown (txthead);
return NULL;
}
/* Add the charset used when generating the clearsigned message */
context = (ArmorContext *)sighead->priv;
pgpAssert (context);
context->charset = pgpenvGetCString (env, PGPENV_CHARSET, NULL);
/* noconv is default, don't put it in */
if( strcmp( context->charset, "noconv" ) == 0) {
context->charset = NULL;
}
*sigtail = pgpJoinAppend (*joinhead);
if (!*sigtail) {
txthead->teardown (txthead);
sighead->teardown (sighead);
return NULL;
}
pgpJoinBuffer (*sigtail, (PGPByte *)"\n", 1);
*texthead = txthead;
*signhead = sighead;
return tail;
}
PGPPipeline **
pgpArmorWriteCreatePgpMimesig (
PGPPipeline **texttail,
PGPPipeline **signtail,
PGPEnv const *env,
PGPFifoDesc const *fd,
PGPRandomContext const *rc,
PgpVersion version, PGPByte *hashlist,
unsigned hashlen)
{
ArmorContext *context, *sigcontext;
PGPPipeline *txthead = NULL, *sighead = NULL;
PGPPipeline **joinhead, **sigtail, **tail;
PGPPipeline **splithead, **splittail;
PGPContextRef cdkContext = pgpenvGetContext( env );
PGPByte sepbits[(NSEPCHARS+7)/8];
PGPSize bodyoff = 0;
PGPUInt32 headerlines = 0;
PGPUInt32 i;
if (!texttail || !signtail || !rc)
return NULL;
splithead = armorDoCreate ( cdkContext,
&txthead, &context, env, version, fd, NULL, 0,
ATYPE_MIMESIG, hashlist, hashlen);
if (!splithead)
return NULL;
/* Create split to take output from clearmime armor module */
joinhead = pgpSplitCreate(cdkContext, splithead);
/* Set second split output to go to signing pipeline */
splittail = pgpSplitAdd (*splithead);
*splittail = *texttail;
tail = pgpJoinCreate ( cdkContext, joinhead, fd);
if (!tail) {
txthead->teardown (txthead);
return NULL;
}
sigtail = armorDoCreate ( cdkContext, &sighead, &sigcontext, env, version,
fd, NULL, 0, ATYPE_MIMESEPSIG, NULL, 0);
if (!sigtail) {
txthead->teardown (txthead);
return NULL;
}
*sigtail = pgpJoinAppend (*joinhead);
if (!*sigtail) {
txthead->teardown (txthead);
sighead->teardown (sighead);
return NULL;
}
/* Create a random message separator */
pgpRandomGetBytes (rc, sepbits, (NSEPCHARS+7)/8);
for (i=0; i<NSEPCHARS; ++i) {
context->mimesigsep[i] = ((sepbits[i/8]>>(i&7))&1) ? '-' : '=';
}
context->mimesigsep[NSEPCHARS] = '\0';
pgpCopyMemory(context->mimesigsep, sigcontext->mimesigsep, NSEPCHARS+1);
bodyoff = 0;
headerlines = 0;
context->pgpmimeversionline = pgpenvGetInt( env,
PGPENV_PGPMIMEVERSIONLINE, NULL, NULL );
if( context->pgpmimeversionline ) {
pgpJoinBuffer (*joinhead, (PGPByte *)MIMESIGHDR1a,
strlen(MIMESIGHDR1a));
bodyoff += strlen(MIMESIGHDR1a);
headerlines += MIMESIGHDRLINESa;
}
pgpJoinBuffer (*joinhead, (PGPByte *)MIMESIGHDR1b, strlen(MIMESIGHDR1b));
pgpJoinBuffer (*joinhead, (PGPByte *)context->mimesigsep, NSEPCHARS);
pgpJoinBuffer (*joinhead, (PGPByte *)MIMESIGHDR2, strlen(MIMESIGHDR2));
bodyoff += strlen(MIMESIGHDR1b) + NSEPCHARS + strlen(MIMESIGHDR2);
headerlines += MIMESIGHDRLINESb;
if (!hashlen) {
pgpJoinBuffer (*joinhead, (PGPByte *)MIMEMIC, strlen(MIMEMIC));
pgpJoinBuffer (*joinhead, (PGPByte *)MIMEDFLTMIC,
strlen(MIMEDFLTMIC));
bodyoff += strlen(MIMEMIC) + strlen(MIMEDFLTMIC);
} else {
while (hashlen--) {
PGPHashVTBL const *hash = NULL;
unsigned j, len;
char hashname[30]; /* lower case name */
hash = pgpHashByNumber ( (PGPHashAlgorithm) (*hashlist++) );
pgpAssert(hash);
len = strlen(hash->name);
pgpAssert (len < sizeof(hashname));
pgpJoinBuffer (*joinhead, (PGPByte *)MIMEMIC,
strlen(MIMEMIC));
for (j=0; j<len; ++j)
hashname[j] = tolower(hash->name[j]);
pgpJoinBuffer (*joinhead, (PGPByte *)hashname,
len);
bodyoff += strlen(MIMEMIC) + len;
if( hashlen ) {
pgpJoinBuffer (*joinhead, (PGPByte *)";", 1);
bodyoff += 1;
}
}
}
pgpJoinBuffer (*joinhead, (PGPByte *)"\n\n", 2);
bodyoff += 2;
headerlines += 2;
context->mimebodyoff = bodyoff;
context->mimeheaderlines = headerlines;
pgpJoinBuffer (*joinhead, (PGPByte *)"--", 2);
pgpJoinBuffer (*joinhead, (PGPByte *)context->mimesigsep, NSEPCHARS);
pgpJoinBuffer (*joinhead, (PGPByte *)"\n", 1);
pgpJoinBuffer (*sigtail, (PGPByte *)"\n--", 3);
pgpJoinBuffer (*sigtail, (PGPByte *)context->mimesigsep, NSEPCHARS);
pgpJoinBuffer (*sigtail, (PGPByte *)"\n", 1);
pgpJoinBuffer (*sigtail, (PGPByte *)MIMEMIDBOUND, strlen(MIMEMIDBOUND));
*texttail = txthead;
*signtail = sighead;
return tail;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -