webpg-npapi 0.6.1
keyedit.h
00001 #ifdef HAVE_W32_SYSTEM
00002 #include <windows.h>
00003 #endif
00004 
00005 #include <stdlib.h>
00006 #include <iostream>
00007 
00008 // GNUGPGHOME need only be populated and all future context init's will use
00009 //  the path as homedir for gpg
00010 //#ifdef HAVE_W32_SYSTEM
00011 //    wchar_t *GNUPGHOME;
00012 //#else
00013 std::string GNUPGHOME;
00014 //#endif
00015 
00016 // A global holder for the current edit_fnc status
00017 std::string edit_status;
00018 
00019 /* Global variables for the handling of UID signing or
00020     deleting signatures on UIDs */
00021 
00022 // subkey_type
00023 std::string gen_subkey_type;
00024 
00025 // subkey_length
00026 std::string gen_subkey_length;
00027 
00028 // subkey_expire
00029 std::string gen_subkey_expire;
00030 
00031 // Flags for subkey generation
00032 bool gen_sign_flag;
00033 bool gen_enc_flag;
00034 bool gen_auth_flag;
00035 
00036 // index number of the UID which contains the signature to delete/revoke
00037 std::string current_uid;
00038 
00039 // index number for the signature to select
00040 std::string current_sig;
00041 
00042 // trust value to assign
00043 std::string trust_assignment;
00044 
00045 // uid name to create
00046 std::string genuid_name;
00047 
00048 // uid email to assign
00049 std::string genuid_email;
00050 
00051 // uid comment to assign
00052 std::string genuid_comment;
00053 
00054 // Used as iter count for current signature index
00055 static int signature_iter;
00056 
00057 // Used as iter count for current notation/description line
00058 static int text_line;
00059 
00060 // Used to store the index for the key/subkey
00061 //  0: Public Key
00062 //  1 &>: Subkeys
00063 std::string key_index;
00064 
00065 // Used to store the value for the new expiration
00066 std::string expiration;
00067 
00068 // Used to store the type of item to revoke
00069 std::string revitem;
00070 
00071 // Used to store the index of the of the revocation reason
00072 // 0: No reason specified
00073 // 1: Key has been compromised
00074 // 2: Key is superseded
00075 // 3: Key is no longer used
00076 // -- UID revocation --
00077 // 4: User ID is no longer used
00078 std::string reason_index;
00079 
00080 // Used to store the revocation description
00081 std::string description;
00082 
00083 // Used to keep track of the current edit iteration
00084 static int step = 0;
00085 
00086 static int flag_step = 0;
00087 
00088 /* An inline method to convert an integer to a string */
00089 inline
00090 std::string i_to_str(const int &number)
00091 {
00092    std::ostringstream oss;
00093    oss << number;
00094    return oss.str();
00095 }
00096 
00097 // Create a dummy passphrase callback for instances where we cannot prevent
00098 //  the agent from prompting the user when we are merely attempting to verify
00099 //  a PGP block (this is needed for GPG2 on Windows)
00100 gpgme_error_t
00101 passphrase_cb (void *opaque, const char *uid_hint, const char *passphrase_info,
00102            int last_was_bad, int fd)
00103 {
00104 #ifdef HAVE_W32_SYSTEM
00105     DWORD written;
00106     WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00107 #else
00108     int res;
00109     std::string pass = "\n";
00110     int passlen = pass.length();
00111     int off = 0;
00112 
00113     do {
00114         res = write (fd, &pass[off], passlen - off);
00115         if (res > 0)
00116         off += res;
00117     }
00118     while (res > 0 && off != passlen);
00119 
00120     return off == passlen ? 0 : gpgme_error_from_errno (errno);
00121 #endif
00122 
00123   return 0;
00124 }
00125 
00126 gpgme_error_t
00127 edit_fnc_sign (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00128 {
00129     /* this is stores the response to a questions that arise during
00130         the edit loop - it is what the user would normally type while
00131         using `gpg --edit-key`. To test the prompts and their output,
00132         you can execute GnuPG this way:
00133             gpg --command-fd 0 --status-fd 2 --edit-key <KEY ID>
00134      */
00135     char *response = NULL;
00136     int error = GPG_ERR_NO_ERROR;
00137     static std::string prior_response = "";
00138     static gpgme_status_code_t status_result;
00139 
00140     if (status != 49 && status != 51)
00141         status_result = status;
00142 
00143     if (fd >= 0) {
00144         if (!strcmp (args, "keyedit.prompt")) {
00145             static int step = 0;
00146 
00147             switch (step) {
00148                 case 0:
00149                     response = (char *) "fpr";
00150                     break;
00151 
00152                 case 1:
00153                     response = (char *) current_uid.c_str();
00154                     break;
00155 
00156                 case 2:
00157                     response = (char *) "tlsign";
00158                     break;
00159 
00160                 default:
00161                     if (status_result && prior_response == "tlsign")
00162                         error = status_result; // there is a problem...
00163                     prior_response = "";
00164                     step = 0;
00165                     response = (char *) "quit";
00166                     break;
00167             }
00168             step++;
00169         }
00170         else if (!strcmp (args, "keyedit.save.okay"))
00171             response = (char *) "Y";
00172         else if (!strcmp (args, "trustsig_prompt.trust_value"))
00173             response = (char *) "1";
00174         else if (!strcmp (args, "trustsig_prompt.trust_depth"))
00175             response = (char *) "1";
00176         else if (!strcmp (args, "trustsig_prompt.trust_regexp"))
00177             response = (char *) "";
00178         else if (!strcmp (args, "sign_uid.okay"))
00179             response = (char *) "y";
00180         else if (!strcmp (args, "passphrase.enter")) {
00181             response = (char *) "";
00182             error = GPG_ERR_BAD_PASSPHRASE;
00183         } else {
00184             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00185             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00186             return 1;
00187         }
00188     }
00189 
00190     if (response) {
00191         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00192         prior_response = response;
00193 #ifdef HAVE_W32_SYSTEM
00194         DWORD written;
00195         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00196         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00197 #else
00198         ssize_t write_result;
00199         write_result = write (fd, response, strlen (response));
00200         write_result = write (fd, "\n", 1);
00201 #endif
00202     }
00203     return error;
00204 }
00205 
00206 
00207 gpgme_error_t
00208 edit_fnc_delsign (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00209 {
00210   /* this works for deleting signatures -
00211     you must populate the global variables before calling this method for this to work -
00212         current_uid = <the index of the UID which has the signature you wish to delete>
00213         current_sig = <the index of signature you wish to delete>  */
00214     char *response = NULL;
00215 
00216     if (fd >= 0) {
00217         if (!strcmp (args, "keyedit.prompt")) {
00218             static int step = 0;
00219 
00220             switch (step) {
00221                 case 0:
00222                     response = (char *) "fpr";
00223                     break;
00224 
00225                 case 1:
00226                     signature_iter = 1;
00227                     response = (char *) current_uid.c_str();
00228                     break;
00229 
00230                 case 2:
00231                     response = (char * ) "delsig";
00232                     break;
00233 
00234                 default:
00235                     step = 0;
00236                     response = (char *) "quit";
00237                     break;
00238             }
00239             step++;
00240         } else if (!strcmp (args, "keyedit.save.okay")) {
00241             response = (char *) "Y";
00242         } else if (!strcmp (args, "keyedit.delsig.valid") || 
00243             !strcmp (args, "keyedit.delsig.invalid") ||
00244             !strcmp (args, "keyedit.delsig.unknown")) {
00245             if (signature_iter == atoi(current_sig.c_str())) {
00246                 response = (char *) "y";
00247                 current_sig = "0";
00248                 current_uid = "0";
00249                 signature_iter = 0;
00250             } else {
00251                 response = (char *) "n";
00252             }
00253             signature_iter++;
00254         } else if (!strcmp (args, "keyedit.delsig.selfsig")) {
00255             response = (char *) "y";
00256         } else if (!strcmp (args, "passphrase.enter")) {
00257             response = (char *) "";
00258         } else {
00259             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00260             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00261             return 1;
00262         }
00263     }
00264 
00265     if (response) {
00266         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00267 #ifdef HAVE_W32_SYSTEM
00268         DWORD written;
00269         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00270         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00271 #else
00272         ssize_t write_result;
00273         write_result = write (fd, response, strlen (response));
00274         write_result = write (fd, "\n", 1);
00275 #endif
00276     }
00277     return 0;
00278 }
00279 
00280 gpgme_error_t
00281 edit_fnc_disable (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00282 {
00283   /* this works for disabling keys */
00284     char *response = NULL;
00285 
00286     if (fd >= 0) {
00287         if (!strcmp (args, "keyedit.prompt")) {
00288             static int step = 0;
00289 
00290             switch (step) {
00291                 case 0:
00292                     response = (char *) "disable";
00293                     break;
00294 
00295                 default:
00296                     step = -1;
00297                     response = (char *) "quit";
00298                     break;
00299             }
00300             step++;
00301         } else if (!strcmp (args, "keyedit.save.okay")) {
00302             response = (char *) "Y";
00303         } else if (!strcmp (args, "passphrase.enter")) {
00304             response = (char *) "";
00305         } else {
00306             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00307             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00308             return 1;
00309         }
00310     }
00311 
00312     if (response) {
00313         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00314 #ifdef HAVE_W32_SYSTEM
00315         DWORD written;
00316         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00317         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00318 #else
00319         ssize_t write_result;
00320         write_result = write (fd, response, strlen (response));
00321         write_result = write (fd, "\n", 1);
00322 #endif
00323     }
00324     return 0;
00325 }
00326 
00327 gpgme_error_t
00328 edit_fnc_enable (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00329 {
00330   /* this enableds a disabled key  */
00331     char *response = NULL;
00332 
00333     if (fd >= 0) {
00334         if (!strcmp (args, "keyedit.prompt")) {
00335             static int step = 0;
00336 
00337             switch (step) {
00338                 case 0:
00339                     response = (char *) "enable";
00340                     break;
00341 
00342                 default:
00343                     step = -1;
00344                     response = (char *) "quit";
00345                     break;
00346             }
00347             step++;
00348         } else if (!strcmp (args, "keyedit.save.okay")) {
00349             response = (char *) "Y";
00350         } else if (!strcmp (args, "passphrase.enter")) {
00351             response = (char *) "";
00352         } else {
00353             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00354             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00355             return 1;
00356         }
00357     }
00358 
00359     if (response) {
00360         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00361 #ifdef HAVE_W32_SYSTEM
00362         DWORD written;
00363         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00364         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00365 #else
00366         ssize_t write_result;
00367         write_result = write (fd, response, strlen (response));
00368         write_result = write (fd, "\n", 1);
00369 #endif
00370     }
00371     return 0;
00372 }
00373 
00374 gpgme_error_t
00375 edit_fnc_assign_trust (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00376 {
00377   /* this assigns the trust to the key 
00378         the string trust_assignment must be populated before calling this method */
00379     char *response = NULL;
00380 
00381     if (fd >= 0) {
00382         if (!strcmp (args, "keyedit.prompt")) {
00383             static int step = 0;
00384 
00385             switch (step) {
00386                 case 0:
00387                     response = (char *) "trust";
00388                     break;
00389 
00390                 default:
00391                     step = 0;
00392                     response = (char *) "quit";
00393                     break;
00394             }
00395             step++;
00396         } else if (!strcmp (args, "edit_ownertrust.value")) {
00397             if (step < 15) {
00398                 response = (char *) trust_assignment.c_str();
00399                 step++;
00400             } else {
00401                 response = (char *) "m";
00402             }
00403         } else if (!strcmp (args, "edit_ownertrust.set_ultimate.okay")) {
00404             response = (char *) "Y";
00405         } else if (!strcmp (args, "passphrase.enter")) {
00406             response = (char *) "";
00407         } else {
00408             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00409             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00410             return 1;
00411         }
00412     }
00413 
00414     if (response) {
00415         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00416 #ifdef HAVE_W32_SYSTEM
00417         DWORD written;
00418         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00419         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00420 #else
00421         ssize_t write_result;
00422         write_result = write (fd, response, strlen (response));
00423         write_result = write (fd, "\n", 1);
00424 #endif
00425     }
00426     return 0;
00427 }
00428 
00429 gpgme_error_t
00430 edit_fnc_add_uid (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00431 {
00432   /* this creates a new UID for the given Key
00433         the strings genuid_name, genuid_email and genuid_comment must be populated before calling this method */
00434 
00435     char *response = NULL;
00436 
00437     if (fd >= 0) {
00438         if (!strcmp (args, "keyedit.prompt")) {
00439             static int step = 0;
00440 
00441             switch (step) {
00442                 case 0:
00443                     response = (char *) "adduid";
00444                     break;
00445 
00446                 default:
00447                     step = -1;
00448                     response = (char *) "quit";
00449                     break;
00450             }
00451             step++;
00452         } else if (!strcmp (args, "keygen.name")) {
00453             response = (char *) genuid_name.c_str();
00454         } else if (!strcmp (args, "keygen.email")) {
00455             if (strlen (genuid_email.c_str()) > 1) {
00456                 response = (char *) genuid_email.c_str();
00457             } else {
00458                 response = (char *) "";
00459             }
00460         } else if (!strcmp (args, "keygen.comment")) {
00461             if (strlen (genuid_comment.c_str()) > 1) {
00462                 response = (char *) genuid_comment.c_str();
00463             } else {
00464                 response = (char *) "";
00465             }
00466         } else if (!strcmp (args, "keyedit.save.okay")) {
00467             response = (char *) "Y";
00468             step = 0;
00469         } else if (!strcmp (args, "passphrase.enter")) {
00470             response = (char *) "";
00471         } else {
00472             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00473             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00474             return 1;
00475         }
00476     }
00477 
00478     if (response) {
00479         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00480 #ifdef HAVE_W32_SYSTEM
00481         DWORD written;
00482         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00483         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00484 #else
00485         ssize_t write_result;
00486         write_result = write (fd, response, strlen (response));
00487         write_result = write (fd, "\n", 1);
00488 #endif
00489     }
00490     return 0;
00491 }
00492 
00493 gpgme_error_t
00494 edit_fnc_delete_uid (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00495 {
00496   /* this deletes a UID for the given Key
00497         the string current_uid must be populated before calling this method */
00498 
00499     char *response = NULL;
00500 
00501     if (fd >= 0) {
00502         if (!strcmp (args, "keyedit.prompt")) {
00503             static int step = 0;
00504 
00505             switch (step) {
00506                 case 0:
00507                     response = (char *) current_uid.c_str();
00508                     break;
00509 
00510                 case 1:
00511                     response = (char *) "deluid";
00512                     break;
00513 
00514                 default:
00515                     step = -1;
00516                     response = (char *) "quit";
00517                     break;
00518             }
00519             step++;
00520         } else if (!strcmp (args, "keyedit.remove.uid.okay")) {
00521             response = (char *) "Y";
00522         } else if (!strcmp (args, "keyedit.save.okay")) {
00523             response = (char *) "Y";
00524             step = 0;
00525         } else if (!strcmp (args, "passphrase.enter")) {
00526             response = (char *) "";
00527         } else {
00528             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00529             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00530             return 1;
00531         }
00532     }
00533 
00534     if (response) {
00535         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00536 #ifdef HAVE_W32_SYSTEM
00537         DWORD written;
00538         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00539         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00540 #else
00541         ssize_t write_result;
00542         write_result = write (fd, response, strlen (response));
00543         write_result = write (fd, "\n", 1);
00544 #endif
00545     }
00546     return 0;
00547 }
00548 
00549 gpgme_error_t
00550 edit_fnc_set_primary_uid (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00551 {
00552   /* this sets a given UID as the primary for the key
00553         the string current_uid must be populated before calling this method */
00554 
00555     char *response = NULL;
00556 
00557     if (fd >= 0) {
00558         if (!strcmp (args, "keyedit.prompt")) {
00559             static int step = 0;
00560 
00561             switch (step) {
00562                 case 0:
00563                     response = (char *) current_uid.c_str();
00564                     break;
00565 
00566                 case 1:
00567                     response = (char *) "primary";
00568                     break;
00569 
00570                 default:
00571                     step = -1;
00572                     response = (char *) "quit";
00573                     break;
00574             }
00575             step++;
00576         } else if (!strcmp (args, "keyedit.remove.uid.okay")) {
00577             response = (char *) "Y";
00578         } else if (!strcmp (args, "keyedit.save.okay")) {
00579             response = (char *) "Y";
00580             step = 0;
00581         } else if (!strcmp (args, "passphrase.enter")) {
00582             response = (char *) "";
00583         } else {
00584             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00585             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00586             return 1;
00587         }
00588     }
00589 
00590     if (response) {
00591         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00592 #ifdef HAVE_W32_SYSTEM
00593         DWORD written;
00594         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00595         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00596 #else
00597         ssize_t write_result;
00598         write_result = write (fd, response, strlen (response));
00599         write_result = write (fd, "\n", 1);
00600 #endif
00601     }
00602     return 0;
00603 }
00604 
00605 gpgme_error_t
00606 edit_fnc_set_key_expire (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00607 {
00608   /* this sets the expiration for a given key
00609         the strings key_index and expiration must be populated before calling this method */
00610 
00611     char *response = NULL;
00612     std::string cmd;
00613 
00614     if (fd >= 0) {
00615         if (!strcmp (args, "keyedit.prompt")) {
00616             static int step = 0;
00617 
00618             switch (step) {
00619                 case 0:
00620                     cmd = "key ";
00621                     cmd += key_index;
00622                     response = (char *) cmd.c_str();
00623                     break;
00624 
00625                 case 1:
00626                     response = (char *) "expire";
00627                     break;
00628 
00629                 default:
00630                     step = -1;
00631                     response = (char *) "quit";
00632                     break;
00633             }
00634             step++;
00635         } else if (!strcmp (args, "keygen.valid")) {
00636             response = (char *) expiration.c_str();
00637         } else if (!strcmp (args, "keyedit.save.okay")) {
00638             response = (char *) "Y";
00639             step = 0;
00640         } else if (!strcmp (args, "passphrase.enter")) {
00641             response = (char *) "";
00642         } else {
00643             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00644             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00645             return 1;
00646         }
00647     }
00648 
00649     if (response) {
00650         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00651 #ifdef HAVE_W32_SYSTEM
00652         DWORD written;
00653         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00654         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00655 #else
00656         ssize_t write_result;
00657         write_result = write (fd, response, strlen (response));
00658         write_result = write (fd, "\n", 1);
00659 #endif
00660     }
00661     return 0;
00662 }
00663 
00664 gpgme_error_t
00665 edit_fnc_revoke_item (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00666 {
00667   /* this revokes a given key, subkey or uid
00668         the global strings revitem, key_index, reason_index and desc_text must be populated
00669         before calling this method */
00670 
00671     char *response = NULL;
00672     std::string cmd;
00673 
00674     if (!strcmp (revitem.c_str(), "revkey")) {
00675             cmd = "key ";
00676             cmd += key_index;
00677     } else if (!strcmp (revitem.c_str(), "revuid")) {
00678             cmd = "uid ";
00679             cmd += current_uid;
00680     } else if (!strcmp (revitem.c_str(), "revsig")) {
00681             cmd = "uid ";
00682             cmd += current_uid;
00683     }
00684 
00685     if (fd >= 0) {
00686         if (!strcmp (args, "keyedit.prompt")) {
00687             static int step = 0;
00688 
00689             switch (step) {
00690                 case 0:
00691                     response = (char *) cmd.c_str();
00692                     break;
00693 
00694                 case 1:
00695                     signature_iter = 0;
00696                     text_line = 1;
00697                     response = (char *) revitem.c_str();
00698                     break;
00699 
00700                 default:
00701                     step = -1;
00702                     response = (char *) "quit";
00703                     break;
00704             }
00705             step++;
00706         } else if (!strcmp (args, "keyedit.revoke.subkey.okay")) {
00707             response = (char *) "Y";
00708         } else if (!strcmp (args, "ask_revoke_sig.one")) {
00709             if (signature_iter == atoi(current_sig.c_str())) {
00710                 response = (char *) "Y";
00711                 current_sig = "0";
00712                 current_uid = "0";
00713                 signature_iter = 0;
00714             } else {
00715                 response = (char *) "N";
00716             }
00717             signature_iter++;
00718         } else if (!strcmp (args, "keyedit.revoke.uid.okay")){
00719             response = (char *) "Y";
00720         } else if (!strcmp (args, "ask_revoke_sig.okay")) {
00721             response = (char *) "Y";
00722         } else if (!strcmp (args, "ask_revocation_reason.code")) {
00723             response = (char *) reason_index.c_str();
00724         } else if (!strcmp (args, "ask_revocation_reason.text")) {
00725             if (text_line > 1) {
00726                 text_line = 1;
00727                 response = (char *) "";
00728             } else {
00729                 text_line++;
00730                 response = (char *) description.c_str();
00731             }
00732         } else if (!strcmp (args, "ask_revocation_reason.okay")) {
00733             response = (char *) "Y";
00734         } else if (!strcmp (args, "keyedit.save.okay")) {
00735             response = (char *) "Y";
00736             step = 0;
00737         } else if (!strcmp (args, "passphrase.enter")) {
00738             response = (char *) "";
00739         } else {
00740             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00741             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00742             return 1;
00743         }
00744     }
00745 
00746     if (response) {
00747         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00748 #ifdef HAVE_W32_SYSTEM
00749         DWORD written;
00750         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00751         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00752 #else
00753         ssize_t write_result;
00754         write_result = write (fd, response, strlen (response));
00755         write_result = write (fd, "\n", 1);
00756 #endif
00757     }
00758     return 0;
00759 }
00760 
00761 gpgme_error_t
00762 edit_fnc_add_subkey (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00763 {
00764   /* this works for adding subkeys */
00765     char *response = NULL;
00766 
00767     if (fd >= 0) {
00768         if (!strcmp (args, "keyedit.prompt")) {
00769             static int step = 0;
00770 
00771             switch (step) {
00772                 case 0:
00773                     response = (char *) "addkey";
00774                     break;
00775 
00776                 default:
00777                     response = (char *) "quit";
00778                     step = -1;
00779                     break;
00780             }
00781             step++;
00782         } else if (!strcmp (args, "keygen.algo")) {
00783             response = (char *) gen_subkey_type.c_str();
00784         } else if (!strcmp (args, "keygen.flags")) {
00785             static int flag_step = 0;
00786 
00787             switch (flag_step) {
00788                 case 0:
00789                     // If the gen_sign_flag is set, we don't need to change
00790                     //  anything, as the sign_flag is set by default
00791                     if (gen_sign_flag) {
00792                         response = (char *) "nochange";
00793                     } else {
00794                         response = (char *) "S";
00795                     }
00796                     break;
00797 
00798                 case 1:
00799                     // If the gen_enc_flag is set, we don't need to change
00800                     //  anything, as the enc_flag is set by default on keys
00801                     //  that support the enc flag (RSA)
00802                     if (gen_enc_flag) {
00803                         response = (char *) "nochange";
00804                     } else {
00805                         response = (char *) "E";
00806                     }
00807                     break;
00808 
00809                 case 2:
00810                     if (gen_auth_flag) {
00811                         response = (char *) "A";
00812                     } else {
00813                         response = (char *) "nochange";
00814                     }
00815                     break;
00816 
00817                 default:
00818                     response = (char *) "Q";
00819                     flag_step = -1;
00820                     break;
00821 
00822             }
00823             flag_step++;
00824         } else if (!strcmp (args, "keygen.size")) {
00825             response = (char *) gen_subkey_length.c_str();
00826         } else if (!strcmp (args, "keygen.valid")) {
00827             response = (char *) gen_subkey_expire.c_str();
00828         } else if (!strcmp (args, "keyedit.save.okay")) {
00829             response = (char *) "Y";
00830         } else if (!strcmp (args, "passphrase.enter")) {
00831             response = (char *) "";
00832         } else {
00833             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00834             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00835             return 1;
00836         }
00837     }
00838 
00839     if (response) {
00840         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00841 #ifdef HAVE_W32_SYSTEM
00842         DWORD written;
00843         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00844         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00845 #else
00846         ssize_t write_result;
00847         write_result = write (fd, response, strlen (response));
00848         write_result = write (fd, "\n", 1);
00849 #endif
00850     }
00851     return 0;
00852 }
00853 
00854 gpgme_error_t
00855 edit_fnc_delete_subkey (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00856 {
00857   /* this works for deleting subkeys */
00858     char *response = NULL;
00859     std::string cmd;
00860     cmd = "key ";
00861     cmd += key_index;
00862     response = (char *) cmd.c_str();
00863 
00864     if (fd >= 0) {
00865         if (!strcmp (args, "keyedit.prompt")) {
00866             static int step = 0;
00867 
00868             switch (step) {
00869                 case 0:
00870                     cmd = "key ";
00871                     cmd += key_index;
00872                     response = (char *) cmd.c_str();
00873                     break;
00874 
00875                 case 1:
00876                     signature_iter = 1;
00877                     response = (char *) "delkey";
00878                     break;
00879 
00880                 default:
00881                     step = -1;
00882                     response = (char *) "quit";
00883                     break;
00884             }
00885             step++;
00886         } else if (!strcmp (args, "keyedit.save.okay")) {
00887             response = (char *) "Y";
00888         } else if (!strcmp (args, "keyedit.remove.subkey.okay")) {
00889             response = (char *) "Y";
00890         } else if (!strcmp (args, "passphrase.enter")) {
00891             response = (char *) "";
00892         } else {
00893             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00894             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00895             return 1;
00896         }
00897     }
00898 
00899     if (response) {
00900         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00901 #ifdef HAVE_W32_SYSTEM
00902         DWORD written;
00903         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00904         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00905 #else
00906         ssize_t write_result;
00907         write_result = write (fd, response, strlen (response));
00908         write_result = write (fd, "\n", 1);
00909 #endif
00910     }
00911     return 0;
00912 }
00913 
00914 gpgme_error_t
00915 edit_fnc_change_passphrase (void *opaque, gpgme_status_code_t status, const char *args, int fd)
00916 {
00917   /* this invokes a passphrase change. all I/O of passphrases should happen with the agent  */
00918     char *response = NULL;
00919 
00920     if (fd >= 0) {
00921         if (!strcmp (args, "keyedit.prompt")) {
00922             static int step = 0;
00923 
00924             switch (step) {
00925                 case 0:
00926                     response = (char *) "passwd";
00927                     break;
00928 
00929                 default:
00930                     step = -1;
00931                     response = (char *) "quit";
00932                     break;
00933             }
00934             step++;
00935         } else if (!strcmp (args, "keyedit.save.okay")) {
00936             response = (char *) "Y";
00937         } else if (!strcmp (args, "passphrase.enter")) {
00938             response = (char *) "";
00939         } else {
00940             fprintf (stdout, "We shouldn't reach this line actually; Line: %i\n", __LINE__);
00941             edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": we should never reach here;";
00942             return 1;
00943         }
00944     }
00945 
00946     if (response) {
00947         edit_status = edit_status + " " + args + ", case " + i_to_str(step) + ": response: " + response + ";";
00948 #ifdef HAVE_W32_SYSTEM
00949         DWORD written;
00950         WriteFile ((HANDLE) fd, response, strlen (response), &written, 0);
00951         WriteFile ((HANDLE) fd, "\n", 1, &written, 0);
00952 #else
00953         ssize_t write_result;
00954         write_result = write (fd, response, strlen (response));
00955         write_result = write (fd, "\n", 1);
00956 #endif
00957     }
00958     return 0;
00959 }
 All Classes Functions