#include "gnupgplugin.h" #include char *txtgpgargslistpublickeys= "--homedir \"%home%\"" " --with-colon" // felder durch : voneinander abgetrennt " --list-public-keys"; // oeffentliche schluessel auflisten char *txtgpgargslistsecretkeys= "--homedir \"%home%\"" " --with-colon" " --list-secret-keys"; // geheime schluessel auflisten char *txtgpgargsimportpublickey= "--homedir \"%home%\"" " --import \"%keyfile%\""; // schluessel importieren char *txtgpgargsexportpublickey= "--homedir \"%home%\"" " --batch" " --yes" // abfragen mit ja beantworten " --armor" // ausgabe als text " --comment \"\"" // kommentar unterdruecken ("Comment: For info see http://www.gnupg.org") " --no-version" // ausgabe der version unterdruecken ("Version: GnuPG v1.0.6 (MingW32)") " --export \"%userid%\""; // export des schluessels %userid% char *txtgpgargsdetectuserid= "--homedir \"%home%\"" " --batch" // interaktion verhindern (daraus folgt fehler) " --decrypt \"%cipherfile%\""; // datei %cipherfile% entschluesseln char *txtgpgargsencrypt= "--homedir \"%home%\"" " --batch" " --yes" // abfragen mit ja beantworten " --armor" // textausgabe " --comment \"\"" // kein kommentar hinzufuegen " --no-version" // keine versions informationen hinzufuegen " --recipient \"%userid%\"" // %userid% des empfaengers " --output \"%cipherfile%\"" // ausgabe in datei %cipherfile% " --encrypt \"%plainfile%\""; // eingabe kommt aus %plainfile% char *txtgpgargsdecrypt= "--homedir \"%home%\"" " --yes" // abfragen mit ja beantworten " --passphrase-fd 0" // passphrase von stdin " --output \"%plainfile%\"" // ausgabe in datei %plainfile% " --decrypt \"%cipherfile%\""; // eingabe kommt aus %cipherfile% char *txtgpgtempdir="C:\\TEMP"; char *txtgpgexecutable=""; char *txtgpghomedirectory=""; // oeffentliche zeichenketten char gpgArgsListPublicKeys[argumentsize]; char gpgArgsListSecretKeys[argumentsize]; char gpgArgsImportPublicKey[argumentsize]; char gpgArgsExportPublicKey[argumentsize]; char gpgArgsDetectUserID[argumentsize]; char gpgArgsEncrypt[argumentsize]; char gpgArgsDecrypt[argumentsize]; char gpgTempdir[fullfilenamesize]; char gpgExecutable[fullfilenamesize]; char gpgHomeDirectory[argumentsize]; // zeichenketten fuer den internen gebrauch char *txtpub="pub"; char *txtsec="sec"; char *txtcrlf="\r\n"; char *txtcolon=":"; char *txtquotationmark="\""; char *txtgpgcolon="gpg:"; char *txtplainfile="%plainfile%"; char *txtcipherfile="%cipherfile%"; char *txtuserid="%userid%"; char *txtkeyfile="%keyfile%"; char *txthome="%home%"; char *txtidseparator=", "; void assembleCommandLine(char *aresult, const char *aexecutable, const char *aargs) { strcpy(aresult,aexecutable); strcat(aresult," "); strcat(aresult,aargs); } void detectKeys(char **aresult, char *aoutput, const char *alabel) { char line[linesize]; char part[linesize]; char *linepos; char *partpos; long i; if (!aresult) { LogMessage("--- GnuPG.detectKeys: Illegal function call: ","aresult==NULL","\n"); return; } if (!*aresult) *aresult=(char*)mir_alloc(1); if (!*aresult) return; strcpy(*aresult,""); linepos=aoutput; do { linepos=getNextPart(line,linepos,txtcrlf); if (!linepos) break; partpos=line; partpos=getNextPart(part,partpos,txtcolon); if (strcmp(part,alabel)==0) { for (i=1; i<=10; i++) { partpos=getNextPart(part,partpos,txtcolon); switch (i) { case 4: appendText(aresult,part); appendText(aresult,txtidseparator); break; case 9: appendText(aresult,part); appendText(aresult,txtcrlf); break; } } } } while (linepos); replace(*aresult, "\\x3a", ":"); } gpgResult gpgListPublicKeys(char **aresult) { pxResult pxresult; char commandline[commandlinesize]; DWORD exitcode; char *output; LogMessage("--- GnuPG.gpgListPublicKeys","","\n"); output=(char*)mir_alloc(1); strcpy(output,""); assembleCommandLine(commandline,gpgExecutable,gpgArgsListPublicKeys); replace(commandline,txthome,gpgHomeDirectory); pxresult=pxExecute(commandline,"",&output,&exitcode); if ((pxresult!=pxSuccess)||(exitcode!=0)) { mir_free(output); return gpgExecuteFailed; } detectKeys(aresult,output,txtpub); mir_free(output); return gpgSuccess; } gpgResult gpgListSecretKeys(char **aresult) { pxResult pxresult; char commandline[commandlinesize]; DWORD exitcode; char *output; LogMessage("--- GnuPG.gpgListSecretKeys","","\n"); output=(char*)mir_alloc(1); strcpy(output,""); assembleCommandLine(commandline,gpgExecutable,gpgArgsListSecretKeys); replace(commandline,txthome,gpgHomeDirectory); pxresult=pxExecute(commandline,"",&output,&exitcode); if ((pxresult!=pxSuccess)||(exitcode!=0)) { mir_free(output); return gpgExecuteFailed; } detectKeys(aresult,output,txtsec); mir_free(output); return gpgSuccess; } gpgResult gpgImportPublicKey(const char *akey) { pxResult pxresult; char commandline[commandlinesize]; char filename[fullfilenamesize]; DWORD exitcode; char *output; LogMessage("--- GnuPG.gpgImportPublicKey","","\n"); if (!writeToFile(filename, akey)) return gpgWriteToFileFailed; output=(char*)mir_alloc(1); strcpy(output,""); assembleCommandLine(commandline,gpgExecutable,gpgArgsImportPublicKey); replace(commandline,txtkeyfile,filename); replace(commandline,txthome,gpgHomeDirectory); pxresult=pxExecute(commandline,"",&output,&exitcode); remove(filename); mir_free(output); if ((pxresult!=pxSuccess)||(exitcode!=0)) return gpgExecuteFailed; return gpgSuccess; } gpgResult gpgExportPublicKey(char *aresult, const char *auserid) { pxResult pxresult; char commandline[commandlinesize]; DWORD exitcode; char *output; LogMessage("--- GnuPG.gpgExportPublicKey","","\n"); output=(char*)mir_alloc(1); strcpy(output,""); assembleCommandLine(commandline,gpgExecutable,gpgArgsExportPublicKey); replace(commandline,txtuserid,auserid); replace(commandline,txthome,gpgHomeDirectory); pxresult=pxExecute(commandline,"",&output,&exitcode); if ((pxresult!=pxSuccess)||(exitcode!=0)) { strcpy(aresult,""); mir_free(output); return gpgExecuteFailed; } strcpy(aresult,output); mir_free(output); return gpgSuccess; } gpgResult gpgDetectUserID(char *aresult, const char *aciphertext) { pxResult pxresult; char commandline[commandlinesize]; char filename[fullfilenamesize]; char line[linesize]; char part[linesize]; char *linepos; char *partpos; DWORD exitcode; char *output; LogMessage("--- GnuPG.gpgDetectUserID","","\n"); strcpy(aresult,""); if (!writeToFile(filename,aciphertext)) return gpgWriteToFileFailed; output=(char*)mir_alloc(1); strcpy(output,""); assembleCommandLine(commandline,gpgExecutable,gpgArgsDetectUserID); replace(commandline,txtcipherfile,filename); replace(commandline,txthome,gpgHomeDirectory); pxresult=pxExecute(commandline,"",&output,&exitcode); remove(filename); if ((pxresult!=pxSuccess)&&(pxresult!=pxSuccessExitCodeInvalid)) { mir_free(output); return gpgExecuteFailed; } linepos=output; do { linepos=getNextPart(line,linepos,txtcrlf); if (strncmp(line,txtgpgcolon,strlen(txtgpgcolon))!=0) { partpos=line; partpos=getNextPart(part,partpos,txtquotationmark); getNextPart(part,partpos,txtquotationmark); linepos=NULL; } } while (linepos!=NULL); strcpy(aresult,part); mir_free(output); return gpgSuccess; } gpgResult gpgEncrypt(char **aresult, const char *auserid, const char *aplaintext) // *aresult MUST be NULL of mir_alloc'ated memory block // on return: if *aresult!=NULL => caller MUST later mir_free it by hands // if isUnicode is true, there works "unicode" mode... // i.e. aplaintext is treated as asciiz+ucs2, // it's length is (strlen(aplaintext)+1)*(sizeof(wchar_t)+1) // we encrypt this asciiz+ucs2 mix to asciiz cyphertext... // the asciiz cyphertext we must convert to asciiz+ucs2... // so, *aresult will be our asciiz+ucs2 cyphertext. { char commandline[commandlinesize]; char plainfile[fullfilenamesize]; char cipherfile[fullfilenamesize]; DWORD exitcode; char *output; if (!aresult) return gpgUnknownError; LogMessage("--- GnuPG.gpgEncrypt","","\n"); if (!writeToFile(plainfile,aplaintext)) return gpgWriteToFileFailed; output=(char*)mir_alloc(1); strcpy(output,""); getTemporaryFileName(cipherfile); assembleCommandLine(commandline,gpgExecutable,gpgArgsEncrypt); replace(commandline,txtcipherfile,cipherfile); replace(commandline,txtplainfile,plainfile); replace(commandline,txtuserid,auserid); replace(commandline,txthome,gpgHomeDirectory); pxResult pxresult=pxExecute(commandline,"",&output,&exitcode); remove(plainfile); if (pxresult!=pxSuccess || exitcode!=0) { mir_free(output); return gpgExecuteFailed; } if (!readFromFile(aresult,cipherfile)) { mir_free(output); return gpgReadFromFileFailed; } remove(cipherfile); mir_free(output); return gpgSuccess; } gpgResult gpgDecrypt(char **aresult, const char *aciphertext, const char *apassphrase) // *aresult MUST be NULL of mir_alloc'ated memory block // on return: if *aresult!=NULL => caller MUST later mir_free it by hands { pxResult pxresult; char commandline[commandlinesize]; char plainfile[fullfilenamesize]; char cipherfile[fullfilenamesize]; char passphrase[linesize]; DWORD exitcode; char *output; BOOL rc; LogMessage("--- GnuPG.gpgDecrypt","","\n"); if (!aresult) return gpgUnknownError; if (!writeToFile(cipherfile,aciphertext)) return gpgWriteToFileFailed; output=(char*)mir_alloc(1); strcpy(output,""); getTemporaryFileName(plainfile); assembleCommandLine(commandline,gpgExecutable,gpgArgsDecrypt); replace(commandline,txtcipherfile,cipherfile); replace(commandline,txtplainfile,plainfile); replace(commandline,txthome,gpgHomeDirectory); strcpy(passphrase,apassphrase); strcat(passphrase,txtcrlf); pxresult=pxExecute(commandline,passphrase,&output,&exitcode); remove(cipherfile); mir_free(output); if (pxresult!=pxSuccess || exitcode!=0) return gpgExecuteFailed; rc=readFromFile(aresult,plainfile); remove(plainfile); return rc?gpgSuccess:gpgReadFromFileFailed; }