📄 translators.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: Translators.c,v 1.16 2002/09/26 06:56:53 sdas Exp $
____________________________________________________________________________*/
// System Headers
#include <windows.h>
#include <assert.h>
// Eudora Headers
#include "emssdk/Mimetype.h"
#include "emssdk/Encoding.h"
// Shared Headers
#include "pgpClientPrefs.h"
#include "pgpClientLib.h"
#include "PGPsc.h"
#include "EncryptSign.h"
#include "DecryptVerify.h"
#include "Prefs.h"
#include "pgpHex.h"
// Project Headers
#include "TranslatorIDs.h"
#include "MapFile.h"
#include "TranslatorUtils.h"
#include "MyMIMEUtils.h"
#include "resource.h"
#define WARN_BIT 0x0001
#define CONTINUE_BIT 0x0002
// Global Variables
extern HINSTANCE g_hinst;
extern PGPContextRef g_pgpContext;
extern PGPtlsContextRef g_tlsContext;
extern HWND g_hwndHidden;
extern char * g_szWipeFile;
long CanTranslateMIMEType( long transContext,
emsMIMEtypeP mimeType,
const char* type,
const char* subType);
BOOL UIWarnYesNo(HWND hwnd, UINT nID, UINT nPrefIndex);
long CanPerformTranslation(
const long trans_id,
const emsMIMEtypeP in_mime,
const long context
)
{
long err = EMSR_CANT_TRANS;
if ( in_mime )
{
switch(trans_id)
{
// manual (aka On-Demand) translators
case kManualEncryptTranslatorID:
case kManualSignTranslatorID:
case kManualEncryptSignTranslatorID:
case kManualDecryptVerifyTranslatorID:
{
if( in_mime && match_mime_type( in_mime,
"text",
"plain") )
{
if( ( context & EMSF_ON_REQUEST ) != 0 )
{
err = EMSR_NOW;
}
}
break;
}
// Mime Translators
case kEncryptTranslatorID:
case kSignTranslatorID:
case kEncryptAndSignTranslatorID:
{
err = EMSR_NOW;
break;
}
case kDecryptTranslatorID:
{
if( in_mime && match_mime_type( in_mime,
"multipart",
"encrypted") )
{
err = CanTranslateMIMEType( context,
in_mime,
"multipart",
"encrypted");
}
break;
}
case kVerifyTranslatorID:
{
if( in_mime && match_mime_type( in_mime,
"multipart",
"signed") )
{
err = CanTranslateMIMEType( context,
in_mime,
"multipart",
"signed");
}
break;
}
}
}
return err;
}
long PerformTranslation(
const long trans_id,
const char* in_file,
const char* out_file,
emsHeaderDataP header,
emsMIMEtypeP in_mime,
emsMIMEtypeP* out_mime
)
{
long pluginReturn = EMSR_UNKNOWN_FAIL;
BOOL bSign = FALSE;
PGPError error = kPGPError_NoErr;
PGPSize mimeBodyOffset = 0;
BOOL bMIME = FALSE;
BOOL bUsePGPMIME = FALSE;
BOOL bManual = TRUE;
BOOL bDisableFYEO = FALSE;
HWND hwndMain;
char szExe[256];
char szDll[256];
char temp_file[256];
assert(in_file);
assert(out_file);
temp_file[0] = 0;
LoadString(g_hinst, IDS_EXE, szExe, sizeof(szExe));
LoadString(g_hinst, IDS_DLL, szDll, sizeof(szDll));
hwndMain = GetForegroundWindow();
switch( trans_id )
{
case kEncryptTranslatorID:
case kSignTranslatorID:
case kEncryptAndSignTranslatorID:
{
bManual = FALSE;
bUsePGPMIME = UsePGPMimeForEncryption(PGPPeekContextMemoryMgr(g_pgpContext));
if(bUsePGPMIME ||
( in_mime && !match_mime_type(in_mime, "text", "plain") ) )
{
bMIME = TRUE;
/* Disable FYEO if there's an attachment or HTML */
if (in_mime && !match_mime_type(in_mime, "text", "plain"))
{
bDisableFYEO = TRUE;
if (!bUsePGPMIME)
/* Warn user that the plug-in is about to use PGP/MIME */
if (!UIWarnYesNo(hwndMain, IDS_W_PGPMIME,
kPGPPrefWin32EudoraOutputPGPMIME))
return EMSR_UNKNOWN_FAIL;
}
}
}
case kManualEncryptTranslatorID:
case kManualSignTranslatorID:
case kManualEncryptSignTranslatorID:
{
char** addresses = NULL;
unsigned long numRecipients = 0;
PGPOptionListRef pgpOptions = NULL;
PGPOptionListRef signOptions = NULL;
char mimeSeparator[kPGPMimeSeparatorSize];
BOOL bEncrypt = FALSE;
BOOL bSign = FALSE;
PGPclRecipientDialogStruct *prds = NULL;
if(bManual)
{
bEncrypt = ((trans_id == kManualSignTranslatorID)
? FALSE : TRUE );
bSign = ((trans_id == kManualEncryptTranslatorID)
? FALSE : TRUE );
}
else
{
DWORD dwMapLength = 0;
char *szMapBuffer = NULL;
char *szContent = NULL;
bEncrypt = ((trans_id == kSignTranslatorID) ? FALSE : TRUE );
bSign = ((trans_id == kEncryptTranslatorID) ? FALSE : TRUE );
szMapBuffer = MapFile( in_file, &dwMapLength );
if ( szMapBuffer )
{
szContent = rfc822_extract_cte(szMapBuffer);
free(szMapBuffer);
}
if (szContent)
{
free(szContent);
bMIME = TRUE;
}
if(!bMIME)
{
// want it to look clean upon decryption
// we need only the text of the message
StripMIMEHeader(in_file);
}
}
if (!bMIME)
{
long lWrapWidth = 0;
if (ByDefaultWordWrap(PGPPeekContextMemoryMgr(g_pgpContext),
&lWrapWidth))
{
HANDLE hFile = NULL;
DWORD dwBytes;
DWORD dwLength;
char *szFileData = NULL;
char *szWrapped = NULL;
hFile = CreateFile(in_file, GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
dwLength = GetFileSize(hFile, NULL);
szFileData = (char *) calloc(sizeof(char), dwLength+1);
ReadFile(hFile, szFileData, dwLength, &dwBytes, NULL);
CloseHandle(hFile);
szFileData[dwLength] = 0;
if (WrapBuffer(&szWrapped, szFileData, (short)lWrapWidth))
{
strcpy(temp_file, in_file);
dwBytes = strlen(temp_file);
temp_file[dwBytes-5]++;
temp_file[dwBytes-6]++;
temp_file[dwBytes-7]++;
hFile = CreateFile(temp_file, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL);
WriteFile(hFile, szWrapped, strlen(szWrapped),
&dwBytes, NULL);
CloseHandle(hFile);
in_file = temp_file;
}
free(szFileData);
free(szWrapped);
}
}
// allocate a recipient dialog structure
prds = (PGPclRecipientDialogStruct *)
calloc(sizeof(PGPclRecipientDialogStruct), 1);
if(prds)
{
char szTitle[256] = {0x00}; // title for recipient dialog
UINT recipientReturn = FALSE; // recipient dialog result
PGPKeySetRef keyset = NULL;
error = PGPclOpenDefaultKeyrings(g_pgpContext,
kPGPOpenKeyDBFileOptions_Mutable,
&(prds->keydbOriginal));
if (IsPGPError(error))
error = PGPclOpenDefaultKeyrings(g_pgpContext,
kPGPOpenKeyDBFileOptions_None,
&(prds->keydbOriginal));
if (IsPGPError(error))
{
char szTitle[255];
char szBuffer[1024];
LoadString(g_hinst, IDS_TITLE_PGPERROR, szTitle, 254);
LoadString(g_hinst, IDS_Q_NOKEYRINGS, szBuffer, 1023);
if (MessageBox(hwndMain, szBuffer, szTitle, MB_YESNO)
== IDYES)
{
char szPath[MAX_PATH];
PGPclGetPath(kPGPclPGPkeysExeFile, szPath, MAX_PATH-1);
PGPclExecute(szPath, SW_SHOW);
}
return EMSR_UNKNOWN_FAIL;
}
if (bEncrypt)
{
// do we have the header structure?
// should we autofind recipients?
if(header)
{
numRecipients = ExtractAddressesFromMailHeader(
header,
&addresses);
}
LoadString(GetModuleHandle("PGPeudora.dll"),
IDS_TITLE_RECIPIENTDIALOG, szTitle, sizeof(szTitle));
prds->context = g_pgpContext;
prds->tlsContext = g_tlsContext;
prds->Version = kPGPCurrentRecipVersion;
prds->hwndParent = hwndMain;
prds->szTitle = szTitle;
prds->dwOptions = kPGPclASCIIArmor;
prds->dwDisableFlags =
kPGPclDisableWipeOriginal |
kPGPclDisableASCIIArmor |
kPGPclDisableSelfDecryptingArchive;
if (!bMIME)
prds->dwDisableFlags |= kPGPclDisableInputIsText;
prds->dwNumRecipients = numRecipients;
prds->szRecipientArray = addresses;
if (bDisableFYEO)
prds->dwDisableFlags |= kPGPclDisableSecureViewer;
// If shift is pressed, force the dialog to pop.
if (GetAsyncKeyState( VK_CONTROL ) & 0x8000)
prds->dwDisableFlags |= kPGPclDisableAutoMode;
// See who we wish to encrypt this to
recipientReturn = PGPclRecipientDialog( prds );
if (prds->keydbAdded != NULL)
{
PGPUInt32 numKeys;
PGPKeySetRef keySet;
PGPNewKeySet(prds->keydbAdded, &keySet);
PGPCountKeys(keySet, &numKeys);
if (numKeys > 0)
PGPclImportKeys(g_pgpContext, g_tlsContext,
prds->hwndParent, keySet, prds->keydbOriginal,
kPGPclNoDialogForValidSingletons);
PGPFreeKeySet(keySet);
PGPFreeKeyDB(prds->keydbAdded);
prds->keydbAdded = NULL;
}
if (!recipientReturn)
{
if (addresses)
FreeRecipientList(addresses, numRecipients);
if (prds->keydbSelected != NULL)
PGPFreeKeyDB(prds->keydbSelected);
PGPFreeKeyDB(prds->keydbOriginal);
free(prds);
return EMSR_UNKNOWN_FAIL;
}
}
if( IsntPGPError(error) )
{
error = PGPBuildOptionList(g_pgpContext, &pgpOptions,
PGPOOutputLineEndType(g_pgpContext,
kPGPLineEnd_CRLF),
(bMIME ?
PGPOPGPMIMEEncoding(g_pgpContext,
TRUE,
&mimeBodyOffset,
mimeSeparator) :
PGPONullOption(g_pgpContext) ),
PGPOLastOption(g_pgpContext) );
}
if(IsntPGPError( error))
{
error = EncryptSignFile(g_hinst, hwndMain,
g_pgpContext, g_tlsContext, szExe,
szDll, (char *) in_file, prds,
pgpOptions, &signOptions, (char *) out_file,
bEncrypt, bSign, FALSE);
PGPFreeOptionList(pgpOptions);
PGPFreeOptionList(signOptions);
}
else
{
PGPclEncDecErrorBox (hwndMain, error);
}
if (addresses)
FreeRecipientList(addresses, numRecipients);
if (prds->keydbSelected != NULL)
PGPFreeKeyDB(prds->keydbSelected);
PGPFreeKeyDB(prds->keydbOriginal);
free(prds);
/* Add a blank line at the beginning to work around
Eudora bug */
if (IsntPGPError(error) && bSign && !bManual && !bMIME)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -