📄 keyserver.c
字号:
/*
* 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 + -