webpg-npapi 0.6.1
|
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 }