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

📄 pgptrustprop.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
		uid = uid->next;
	}
	if( IsntNull( uid ) ) {
		udata = pgpFetchObject( uid, &len );
		hlen = pgpPktBufferHeaderLen( udata );
		strncpy (buserid, (char *) udata+hlen, pgpMin(len-hlen, 255));
		buserid[len-hlen] = '\0';
		fputs (buserid, f);
	} else {
		fputs ("<null userid>", f);
	}
	return 0;
}

static int
pgpDebugPrintKey(FILE *f, PGPKeyDBObj *key)
{

	pgpDebugPrintKeyID (f, key);
	fprintf (f, "(");
	pgpDebugPrintKeyUserID (f, key);
	fprintf (f, ")");
	return 0;
}

static void
pgpDebugPrintPath(FILE *f, Path *path)
{
	fprintf (f, " Path ");
	while (path) {
		fprintf (f, "from ");
		pgpDebugPrintKey (f, path->src);
		fprintf (f, " to ");
		pgpDebugPrintKey (f, path->dest);
		fprintf (f, ", conf: %g\n", path->confidence);
		path = path->next;
		if( IsntNull(path) )
			fprintf (f, "  ...segment ");
	}
}

static void
pgpDebugPrintPathList(FILE *f, PathList *pl)
{
	fprintf (f, "Begin PathList\n");
	while (pl) {
		fprintf (f, " (conf=%g) ", pl->confidence);
		pgpDebugPrintPath (f, pl->path);
		pl = pl->next;
	}
	fprintf (f, "End PathList\n");
}

#endif /* DEBUGPATH */

static double pathConfidence (Path *path);



/* Allocate a Path segment */
static Path *
pathAlloc (PGPKeyDB *db)
{
	Path       *path = db->paths;

	if( IsntNull(path) ) {
		db->paths = path->next;
	} else {
		path = (Path *) memPoolAlloc (&db->pathpool, sizeof(Path),
			alignof(Path));
	}
	return path;
}

/* Free a Path segment */
static void
pathFree (Path *path, PGPKeyDB *db)
{
	if( IsNull(path) )
		return;
	path->next = db->paths;
	db->paths = path;
}

/* Free an entire Path */
static void
pathFreeAll (Path *phead, PGPKeyDB *db)
{
	Path **ptail;

	if( IsNull(phead) )
		return;
	ptail = &phead->next;
	while (*ptail) {
		ptail = &(*ptail)->next;
	}
	*ptail = db->paths;
	db->paths = phead;
}

/* Allocate a PathList element */
static PathList *
pathListAlloc (PGPKeyDB *db)
{
	PathList   *plist = db->pathlists;

	if( IsntNull(plist) ) {
		db->pathlists = plist->next;
		plist->next = NULL;
	} else {
		plist = (PathList *) memPoolAlloc (&db->pathpool,
					sizeof(PathList), alignof(PathList));
	}
	return plist;
}

#if 0
/* Free a PathList element, also freeing any path it points to */
static void
pathListFree (PathList *plist, PGPKeyDB *db)
{
	if( IsntNull(plist->path) )
		pathFreeAll (plist->path, db);
	plist->path = 0;
	plist->confidence = 0.;
	plist->next = db->pathlists;
	db->pathlists = plist;
}
#endif

/* Free a whole PathList, also freeing the Paths it points to */
static void
pathListFreeAll (PathList *plhead, PGPKeyDB *db)
{
	PathList **pltail = &plhead->next;
	while (*pltail)
		pltail = &(*pltail)->next;
	*pltail = db->pathlists;
	db->pathlists = plhead;
	while (plhead != *pltail) {
		pathFreeAll (plhead->path, db);
		plhead->path = 0;
		plhead->confidence = 0.;
		plhead = plhead->next;
	}
}


/* Add a Path segment to a Path
 *
 * Returns	updated Path tail pointer
 *
 * tail		tail pointer for Path to be added to
 * seg		pointer to Path segment to add
 *
 */
static Path **
pathAddSeg (Path **tail, Path *seg)
{
	seg->next = *tail;
	*tail = seg;
	return &seg->next;
}

/*
 * Make a copy of a Path, leaving the original untouched.
 *
 * Returns	pointer to new cloned path
 *
 * p1		pointer to the path to be cloned
 * db		KeyDB used for allocations of new path segments
 *
 */
static Path *
pathClone (Path *p1, PGPKeyDB *db)
{
	Path       *phead = NULL,
	          **ptail = &phead;

	while (p1) {
		*ptail = pathAlloc(db);
		if( IsNull(*ptail) )
			return NULL;
		**ptail = *p1;
		p1 = p1->next;
		ptail = &(*ptail)->next;
	}
	return phead;
}

/* Add a copy of a Path to the PathList
 *
 * Returns	tail pointer of updated PathList
 *
 * tail		tail pointer of PathList to be added to
 * path		pointer to Path to add to the PathList
 * db		PGPKeyDB to use for memory allocations
 *
 */
static PathList **
pathListAddPathClone (PathList **tail, Path *path, PGPKeyDB *db)
{
	PathList   *pl;

	pl = pathListAlloc(db);
	if( IsNull(pl) )
		return NULL;
	if( IsntNull(path) )
	{
		pl->path = pathClone (path, db);
		pl->confidence = pathConfidence (path);
	} else {
		pl->path = NULL;
		pl->confidence = 1.0;
	}
	pl->next = *tail;
	*tail = pl;
	return &pl->next;
}


/* Calculate the confidence associated with a path. */
static double
pathConfidence (Path *path)
{
	double     conf = 1.0;

	while (path) {
		conf *= path->confidence;
		path = path->next;
	}
	return conf;
}

/*
 * Prune the PathList to keep only the highest-confidence pathmax Paths.
 * Return the new PathList, free the no longer used Paths.
 *
 * Returns	new PathList with no more than pathmax paths
 *
 * plist	PathList to be pruned
 * pathmax	maximum number of paths to allow
 * db		PGPKeyDB to use for memory allocations
 *
 */
static PathList *
pathListPrune (PathList *plist, unsigned pathmax, PGPKeyDB *db)
{
	PathList   *iplist;			/* Copy of plist */
	PathList  **pl1,			/* Iterator over plist */
	          **maxpl1;			/* Max confidence pl1 pointer */
	PathList   *nplist,			/* New pathlist head */
	          **nptail;			/* New pathlist tail */
	unsigned    npaths,			/* Number of paths in plist initially */
	            newnpaths;		/* Number of paths in final nplist */
	double      maxconf;		/* Best confidence value so far */

	/* Calculate confidence value for each path */
	iplist = plist;
	npaths = 0;
	while (plist) {
		npaths += 1;
		pgpAssert( plist->confidence == pathConfidence (plist->path) );
		plist = plist->next;
	}
	plist = iplist;

	/* Initialize the new path list */
	nplist = plist;
	if( npaths > pathmax ) {
		nplist = NULL;
		nptail = &nplist;
		newnpaths = pgpMin (pathmax, npaths);
		while (newnpaths--) {
			/* Add the best path from plist to nplist */
			pl1 = &plist;
			maxconf = 0.;
			maxpl1 = pl1;
			while (*pl1) {
				/* Find best path in plist in **maxpl1 */
				if( (*pl1)->confidence > maxconf ) {
					maxconf = (*pl1)->confidence;
					maxpl1 = pl1;
				}
				pl1 = &(*pl1)->next;
			}
			*nptail = *maxpl1;
			*maxpl1 = (*maxpl1)->next;
			nptail = &(*nptail)->next;
			*nptail = NULL;
		}

		if( IsntNull(plist) )
			pathListFreeAll (plist, db);
	}
	return nplist;
}


/*
 * Append a (copy of a) second path to the first, removing common segments.
 * Return pointer to "next" pointer of last segment (and pass that as ptail)
 *
 * Return	tail pointer for updated Path
 *
 * phead	pointer to Path which gets appended to
 * ptail	tail pointer for Path which gets appended to
 * p2		pointer to Path to append (a copy of)
 * db		PGPKeyDB to use for memory allocations
 *
 */
static Path **
pathUnion (Path *phead, Path **ptail, Path *p2, PGPKeyDB *db)
{
	Path       *p1;
	Path      **iptail = ptail;

	/* Add path p2 but skip those segments in p1 */
	for ( ; p2; p2 = p2->next) {
		p1 = phead;
		for (p1=phead; p1 && p1 != *iptail; p1 = p1->next) {
			/* Eliminate path segments which are in there already */
			if( p2->src == p1->src && p2->dest == p1->dest ) {
				/* Make sure our confidence rules are working */
				pgpAssert (p2->confidence == p1->confidence);
				break;
			}
		}
		if( IsntNull(p1) && p1 != *iptail )
			continue;
		*ptail = pathAlloc(db);
		if( IsNull(*ptail) )
			return NULL;
		**ptail = *p2;
		ptail = &(*ptail)->next;
		*ptail = NULL;
	}
	return ptail;
}

/*
 * Calculate the confidence for a list of paths.  We add the confidence for
 * each path, subtrace the confidence for the unions of all pairs of paths,
 * add the confidence for the unions for all the triples, and so on.
 * We actually do this by taking each subset of the paths, unioning them,
 * calculating the confidence for that path, and adding or subtracting it
 * based on the parity.
 */
static double
pathListConfidence (PathList *plist, PGPKeyDB *db)
{
    unsigned        pathcount,
                    mask,
	                tmask;
    PathList       *iplist = plist;
    double          conf = 0.;

#ifdef DEBUGPATH
	fprintf (stdout, "Maurer alg:\n");
#endif

	pathcount = 0;
	while (plist) {
		++pathcount;
		plist = plist->next;
	}
	plist = iplist;

	pgpAssert (pathcount < sizeof(unsigned) * 8);
	for (mask=1; mask < (1U<<pathcount); ++mask) {
		double pathconf;
		Path *phead=NULL, **ptail=&phead;
		int oddparity = 0;
		plist = iplist;
		tmask = mask;
		while (plist && tmask) {
			if( tmask & 1 ) {
				ptail = pathUnion (phead, ptail, plist->path, db);
				oddparity = !oddparity;
			}
			plist = plist->next;
			tmask >>= 1;
		}
		pathconf = pathConfidence (phead);
#ifdef DEBUGPATH
		fprintf (stdout, "%sing %g: ", oddparity?" add":" subb",pathconf);
		pgpDebugPrintPath (stdout, phead);
#endif
		if( oddparity )
			conf += pathconf;
		else
 			conf -= pathconf;
		pathFreeAll (phead, db);
		phead = NULL;
		ptail = &phead;
	}
#ifdef DEBUGPATH
	fprintf (stdout, "Net of %g\n", conf);
#endif
	return conf;
}

/*
 * Find the confidence level to use for the given key.
 * This is difficult in this trust model because we generally don't
 * have validity on the userids associated with the key, since there is
 * no well defined (nor arbitrarily imposed) ordering of the graph.
 * The result is that when we do our calculation we may end up with a
 * de facto validity on a key/userid that has no relation to the (cached)
 * validity stored on the key.
 *
 * So we have a set of heuristics to choose the confidence associated
 * with some userid, to wit:
 *
 * If all the userids have at least some validity, we choose the
 * confidence associated with the most valid userid.  Otherwise we
 * just choose the lowest confidence of all the userids.  The reason
 * for the second case is so that if we have a true userid and a false
 * userid, but the true userid doesn't have validity yet, while the
 * false userid has a little tiny bit of validity, we don't want to
 * choose the confidence of the false userid, which might be very
 * high.  It might be that the next step in the path will give high
 * validity to the true (but low confidence) userid.  We would end up
 * counting this key as both high confidence and high validity, which
 * may be wron
 *
 * This heuristic might seem to have the problem that if you get a new userid
 * for a trusted
 * key its trust will go away until either the new userid gets some validity

⌨️ 快捷键说明

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