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

📄 keyserver.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * keyserver.c
 *
 * Copyright (C) 1997 Pretty Good Privacy, Inc.  All rights reserved.
 *
 * $Id: keyserver.c,v 1.1.2.4.2.1 1997/07/14 16:29:55 quark Exp $
 */

#include "config.h"

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <netdb.h>

#include "pgpKeyDB.h"
#include "pgpMem.h"
#include "pgpOutput.h"
#include "pgpUserIO.h"

#include "keyserver.h"

struct _error_table {
    const char *ServerMessage;
    const char *OutputMessage;
    Boolean IsError;
}ErrorTable[] =
{
    {"Key block corrupt: pubkey decode failed",
     "Key block invalid at server.\n", TRUE},
    {"Key block added to key server database.\n  New public keys added: ",
     "%i public key(s) added.\n", FALSE},
    {"Key block in add request contained no new\n\
keys, userid's, or signatures.",
     "The keyserver already contained all the keys, userids and signatures.\n",
     FALSE},
    {"\0", 0, 0}
};

struct _error_string_table {
    unsigned long RawCode;
    unsigned long StringID;
}ErrToStringTable[] =
{
#if 0
/*The commented out errors are internal errors or problems we shouldn't see
 *(ie, if IDS_ERR_UNABLE_TO_LOAD_LIBRARY happened, we wouldn't be loaded to
 *display the error.)
 */
    {ERR_UNABLE_TO_LOAD_LIBRARY,        IDS_ERR_UNABLE_TO_LOAD_LIBRARY},
/*  {ERR_NO_FUNCS_AVAILABLE,            IDS_ERR_NO_FUNCS_AVAILABLE}, */
/*  {ERR_LIBRARY_NOT_LOADED,            IDS_ERR_LIBRARY_NOT_LOADED}, */
/*  {ERR_BAD_PARAM,                     IDS_ERR_BAD_PARAM}, */
/*  {ERR_FUNCTION_NOT_IN_LIB,           IDS_ERR_FUNCTION_NOT_IN_LIB}, */
    {ERR_USER_NOT_FOUND,                IDS_ERR_USER_NOT_FOUND},
    {ERR_USER_CANCEL,                   0}, /*No bonus boxes!*/
    {ERR_KEYRING_FAILURE,               IDS_ERR_KEYRING_FAILURE},
    {ERR_MALLOC_FAILURE,                IDS_ERR_MALLOC_FAILURE},
    {ERR_DATA_WAIT_TIMEOUT,             IDS_ERR_DATA_WAIT_TIMEOUT},
    {ERR_SOCKET_ERROR,                  IDS_ERR_SOCKET_ERROR},
    {ERR_HOST_NOT_FOUND,                IDS_ERR_HOST_NOT_FOUND},
    {ERR_UNABLE_TO_OPEN_SOCKET,         IDS_ERR_UNABLE_TO_OPEN_SOCKET},
    {ERR_MANY_NOT_FOUND,                IDS_ERR_MANY_NOT_FOUND},
    {ERR_NO_RESPONSE_FROM_SERVER,       IDS_ERR_UNKNOWN_SERVER_RESPONSE},
#endif
    {0,                                 0}
};

static unsigned long ReceiveBuffer(char **buffer,
				   int sockfd);
static unsigned long ProcessSendReturn(char *buffer);
static void DisplayKSError(unsigned long ReturnCode);
static int UrlEncode(char **Dest, char *Source);
static void ConvertKeyIDToString (char *sz);
static unsigned long AddKeySetWithConfirm(PGPKeySet *pSourceKeySet,
					  PGPKeySet *pDestKeySet,
					  unsigned long *NumKeysFound);
static int MassageUserId(char **UserId, char *Start, char *End);
static int PGPkeyserverAddKeyBuffer(char *Buffer,
				    PGPKeySet *pKeyRings,
				    unsigned long *NumKeysFound);

int PGPkeyserverGetAndAddKeys(char *UserId,
			      PGPKeySet *pAddFromKeyRing,
			      PGPKeySet *pKeyRings,
			      unsigned long *NumKeysFound,
			      char *keyserver,
			      unsigned short port)
{
    char *KeyBuffer = NULL;
    int ReturnCode = PGPERR_OK;
    char *Start, *End, *IntUserId = NULL;
    unsigned long NumKeys = 0, NumNotFound = 0;

    assert(UserId || pKeyRings);
    assert(NumKeysFound);

    *NumKeysFound = 0;

    if(UserId) {
	Start = strchr(UserId, '\n');
	while(Start && *Start) {
	    ++NumKeys;
	    Start = strchr(Start, '\n');
	    if(Start)
		++Start;
	}

	if(!NumKeys)
	    NumKeys = 1;

	Start = End = UserId;
	while(Start && *Start && (ReturnCode == PGPERR_OK)) {
	    while(End && *End && *End != '\n') {
		++End;
	    }

	    if(MassageUserId(&IntUserId, Start, End) == PGPERR_OK) {
	        StatusOutput(TRUE, "GETTING_KEY_FOR", IntUserId);
		ReturnCode = GetKeyInfoHkp(keyserver,
					   port,
					   &KeyBuffer,
					   IntUserId);
		if(ReturnCode == PGPERR_OK) {
		    ReturnCode = PGPkeyserverAddKeyBuffer(KeyBuffer,
							  pKeyRings,
							  NumKeysFound);
		    if(KeyBuffer)
			pgpFree(KeyBuffer);
		}
		else
		{
		    if(ReturnCode != ERR_USER_NOT_FOUND)
			DisplayKSError(ReturnCode);
		    else
			++NumNotFound;
		}
	    }
	
	    if(IntUserId) {
		pgpFree(IntUserId);
		IntUserId = NULL;
	    }

	    while(End && *End && *End == '\n')
		++End;

	    Start = End;
	}

	switch(NumNotFound) {
	    case 0:
		break;
		
	    case 1:
		DisplayKSError(ERR_USER_NOT_FOUND);
		break;

	    default:
		DisplayKSError(ERR_MANY_NOT_FOUND);
		break;
	}
    }
    else
    {
	if(pKeyRings && pAddFromKeyRing) {
	    PGPKeyIter* pKeyIter = NULL;
	    PGPKey* pKey = NULL;
	    PGPKeyList* pKeyList = NULL;
	    PGPKeySet *pReceivedSet = NULL;
	    char KeyIdBuf[64];
	    unsigned int KeyIdSize = sizeof(KeyIdBuf);
	    char *MultiKeyBuffer = NULL;
	    static int count = 0;

	    pKeyList = pgpOrderKeySet (pAddFromKeyRing, kPGPUserIDOrdering);
	    if(pKeyList) {
		pKeyIter = pgpNewKeyIter (pKeyList);
		
		if(pKeyIter) {
		    pKey = pgpKeyIterNext(pKeyIter);
		
		    while (pKey && (ReturnCode == PGPERR_OK)) {
			pgpGetKeyString(pKey,
					kPGPKeyPropKeyId,
					KeyIdBuf,
					(size_t *) &KeyIdSize);
			ConvertKeyIDToString(KeyIdBuf);
			StatusOutput(TRUE, "GETTING_KEY_FOR", KeyIdBuf);
			ReturnCode = GetKeyInfoHkp(keyserver,
						   port,
						   &KeyBuffer,
						   KeyIdBuf);
			if(ReturnCode == PGPERR_OK) {
			    if(KeyBuffer) {
				if(!MultiKeyBuffer) {
				    MultiKeyBuffer =
					pgpAlloc((strlen(KeyBuffer) + 1) *
					       sizeof(char));
				    *MultiKeyBuffer = '\0';
				}
				else {
				    pgpRealloc((void **) &MultiKeyBuffer,
					       (strlen(KeyBuffer) +
						strlen(MultiKeyBuffer) + 1) *
					       sizeof(char));
				}
				if(MultiKeyBuffer)
				    strcat(MultiKeyBuffer, KeyBuffer);
				
				pgpFree(KeyBuffer);
			    }
			}
			else {
			    if(ReturnCode == ERR_USER_NOT_FOUND)
				++NumNotFound;
			    else
				DisplayKSError(ReturnCode);
			}
			pKey = pgpKeyIterNext(pKeyIter);
		    }
		    pgpFreeKeyIter(pKeyIter);
		}
		pgpFreeKeyList(pKeyList);
		
		switch(NumNotFound) {
		    case 0:
			break;

		    case 1:
			DisplayKSError(ERR_USER_NOT_FOUND);
			break;

		    default:
			DisplayKSError(ERR_MANY_NOT_FOUND);
			break;
		}

		if(MultiKeyBuffer) {
		    pReceivedSet =
			pgpImportKeyBuffer((unsigned char *) MultiKeyBuffer,
					   strlen(MultiKeyBuffer));
		
		    ++count;
		    if(pReceivedSet) {
			ReturnCode = AddKeySetWithConfirm(pReceivedSet,
							  pKeyRings,
							  NumKeysFound);
			pgpFreeKeySet(pReceivedSet);
		    }
		    pgpFree(MultiKeyBuffer);
		}
	    }
	}
	else
	    ReturnCode = ERR_BAD_PARAM;
    }

    return(ReturnCode);
}

int GetKeyInfoHkp(char *keyserver,
		  unsigned short port,
		  char **KeyBuffer,
		  char *UserId)
{
    struct hostent *pHostEnt;
    struct sockaddr_in server_info;
    struct in_addr ip;
    int sockfd;
    char buffer[8192];
    int ReturnCode = PGPERR_OK;

    StatusOutput(TRUE, "LOOKING_UP_HOST", keyserver);

    if((pHostEnt = gethostbyname(keyserver))) {
	StatusOutput(TRUE, "ESTABLISHING_CONNECTION");
	memcpy(&ip, pHostEnt->h_addr, sizeof(ip));
	server_info.sin_addr = ip;
	server_info.sin_port = htons(port);
	server_info.sin_family = pHostEnt->h_addrtype;
#if 0
	if((sockfd =
	    socket(pHostEnt->h_addrtype, SOCK_STREAM, 0)))
#endif
	if((sockfd =
	    socket(server_info.sin_family, SOCK_STREAM, 0)) >= 0) {
	    if(!connect(sockfd,
			(struct sockaddr *) & server_info,
			sizeof(server_info))) {
		StatusOutput(TRUE, "SENDING_REQUEST");
		sprintf(buffer,
			"GET /pks/lookup?op=get&exact=on&search=%s HTTP/1.0\n",
			UserId);
		strcat(buffer, "User-Agent: PGP/5.0 (Unix)\n\r\n\r");
		send(sockfd, buffer, strlen(buffer), 0);
		StatusOutput(TRUE, "RECEIVING_DATA");
		ReturnCode =
		    ReceiveBuffer(KeyBuffer, sockfd);
		StatusOutput(TRUE, "CLEANING_UP");

		if(ReturnCode == PGPERR_OK) {
		    if(strstr(*(KeyBuffer), "BEGIN PGP"))
			ReturnCode = PGPERR_OK;
		    else
			ReturnCode = ERR_USER_NOT_FOUND;
		    StatusOutput(TRUE, "COMPLETE");
		}
	    }
	    else
		ReturnCode = ERR_UNABLE_TO_OPEN_SOCKET;
	    close(sockfd);
	}
	else
	    ReturnCode = ERR_UNABLE_TO_OPEN_SOCKET;
    }
    else
	ReturnCode = ERR_HOST_NOT_FOUND;

    return(ReturnCode);
}

int PutKeyInfoHkp(char *keyserver,
	       unsigned short port,
	       char *KeyBuffer)
{
    struct hostent *pHostEnt;
    struct in_addr ip;
    struct sockaddr_in server_info;
    int sockfd;
    char *buffer, *ErrBuffer = NULL;
    char *TempBuffer;
    int ReturnCode = PGPERR_OK;

    StatusOutput(TRUE, "LOOKING_UP_HOST", keyserver);

    if((pHostEnt = gethostbyname(keyserver))) {
	StatusOutput(TRUE, "ESTABLISHING_CONNECTION");
	memcpy(&ip, pHostEnt->h_addr, sizeof(ip));
	server_info.sin_addr = ip;
	server_info.sin_port = htons(port);
	server_info.sin_family = pHostEnt->h_addrtype;
	
	if((sockfd = socket(server_info.sin_family, SOCK_STREAM, 0)) >= 0) {
	    if(!connect(sockfd,
			(struct sockaddr *) & server_info,
			sizeof(server_info))) {
		StatusOutput(TRUE, "SENDING_KEY");
		UrlEncode(&TempBuffer, KeyBuffer);
		if(TempBuffer) {
		    buffer =
			pgpAlloc((strlen(TempBuffer) + 512) * sizeof(char));
		    if(buffer) {
			sprintf(buffer,
				"POST /pks/add HTTP/1.0\nUser-Agent:\
PGP/5.0 (Unix)\nContent-length: %i\n\nkeytext=",
				strlen(TempBuffer) + 8);
			strcat(buffer, TempBuffer);
			send(sockfd, buffer, strlen(buffer), 0);
			StatusOutput(TRUE, "RECEIVING_RESPONSE");
			pgpFree(buffer);
			ReturnCode =
			    ReceiveBuffer(&ErrBuffer, sockfd);
			StatusOutput(TRUE, "CLEANING_UP");
		    }
		    pgpFree(TempBuffer);
		}
	    }
	    else
		ReturnCode = ERR_UNABLE_TO_OPEN_SOCKET;
	    close(sockfd);
	}
	else
	    ReturnCode = ERR_UNABLE_TO_OPEN_SOCKET;
    }
    else {
	ReturnCode = ERR_HOST_NOT_FOUND;
    }

    if(ErrBuffer) {
	ProcessSendReturn(ErrBuffer);
	pgpFree(ErrBuffer);
    }
    else {
	if (ReturnCode == PGPERR_OK) {
	    ReturnCode = ERR_NO_RESPONSE_FROM_SERVER;
	}
    }

    if(ReturnCode != PGPERR_OK)
	DisplayKSError(ReturnCode);

    return(ReturnCode);
}

int GetKeyInfoHttp(char *keyserver,
		   unsigned short port,
		   char *file,
		   char **KeyBuffer)
{
    struct hostent *pHostEnt;
    struct sockaddr_in server_info;
    struct in_addr ip;
    int sockfd;
    char buffer[8192];
    int ReturnCode = PGPERR_OK;

    StatusOutput(TRUE, "LOOKING_UP_HOST", keyserver);

    if((pHostEnt = gethostbyname(keyserver))) {
	StatusOutput(TRUE, "ESTABLISHING_CONNECTION");
	memcpy(&ip, pHostEnt->h_addr, sizeof(ip));
	server_info.sin_addr = ip;
	server_info.sin_port = htons(port);
	server_info.sin_family = pHostEnt->h_addrtype;
#if 0
	if((sockfd =
	    socket(pHostEnt->h_addrtype, SOCK_STREAM, 0)))
#endif
	if((sockfd =
	    socket(server_info.sin_family, SOCK_STREAM, 0)) >= 0) {
	    if(!connect(sockfd,
			(struct sockaddr *) & server_info,
			sizeof(server_info))) {
		StatusOutput(TRUE, "SENDING_REQUEST");
		sprintf(buffer,
			"GET %s HTTP/1.0\n",
			file);
		strcat(buffer, "User-Agent: PGP/5.0 (Unix)\n\r\n\r");
		send(sockfd, buffer, strlen(buffer), 0);
		StatusOutput(TRUE, "RECEIVING_DATA");
		ReturnCode =
		    ReceiveBuffer(KeyBuffer, sockfd);
		StatusOutput(TRUE, "CLEANING_UP");

⌨️ 快捷键说明

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