From 4101ee8ff9bc818f40dc0173b1434761f187597f Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Tue, 22 Nov 2011 18:30:08 +0000 Subject: added GnuPG git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@197 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- GnuPG/gpg.cpp | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 GnuPG/gpg.cpp (limited to 'GnuPG/gpg.cpp') diff --git a/GnuPG/gpg.cpp b/GnuPG/gpg.cpp new file mode 100644 index 0000000..c258ea1 --- /dev/null +++ b/GnuPG/gpg.cpp @@ -0,0 +1,386 @@ +#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; +} -- cgit v1.2.3