protected virtual int KeyEditCallback(IntPtr handle, KeyEditStatusCode status, string args, Stream fd) { if (fd != null) { fd.Write(new byte[] { (byte)'q', (byte)'u', (byte)'i', (byte)'t', (byte)'\n' }, 0, 5); fd.Flush(); } throw new NotImplementedException("The function KeyEditCallback is not implemented."); }
protected virtual int KeyEditCallback(IntPtr handle, KeyEditStatusCode status, string args, int fd) { libgpgme.NativeMethods.gpgme_io_write(fd, new[] { (byte)'q', (byte)'u', (byte)'i', (byte)'t', (byte)'\n' }, (UIntPtr)5); throw new NotImplementedException("The function KeyEditCallback is not implemented."); }
private byte[] EnableDisableHandler(KeyEditStatusCode status, string args, Stream fd) { PgpEnableDisableOptions endisOptions = settings.endisOptions; string output = ""; if (args != null) { if (args.Equals("keyedit.prompt")) { if (!endisOptions.cmdSend) { switch (endisOptions.OperationMode) { case PgpEnableDisableOptions.Mode.Enable: output = "enable"; break; case PgpEnableDisableOptions.Mode.Disable: output = "disable"; break; } endisOptions.cmdSend = true; } else { output = "quit"; } return ToU8(output); } } return new byte[0]; }
private byte[] ExpireHandler(KeyEditStatusCode status, string args, Stream fd) { PgpExpirationOptions expireOptions = settings.expireOptions; string output = ""; if (args != null) { if (args.Equals("keyedit.prompt") && !expireOptions.cmdSend) { if (expireOptions.SelectedSubkeys != null && (expireOptions.nsubkey < expireOptions.SelectedSubkeys.Length)) { output = "key " + expireOptions.SelectedSubkeys[expireOptions.nsubkey++].ToString(); } else { expireOptions.cmdSend = true; output = "expire"; } return ToU8(output); } // Expire date in days if (args.Equals("keygen.valid")) { if (expireOptions.IsInfinitely || (expireOptions.ExpirationDate.CompareTo(DateTime.Now) < 0)) output = "0"; else output = (expireOptions.ExpirationDate - DateTime.Now).Days.ToString(); return ToU8(output); } if (args.Equals("keyedit.save.okay")) { if (!expireOptions.forceQuit) output = "Y"; else { // maybe an other gnupg process is editing this key at the same time output = "N"; } return ToU8(output); } if (args.Equals("keyedit.prompt") && expireOptions.forceQuit) { output = "quit"; return ToU8(output); } if (args.Equals("keyedit.prompt")) { expireOptions.forceQuit = true; output = "save"; return ToU8(output); } } return new byte[0]; }
private byte[] AddSubkeyHandler(KeyEditStatusCode status, string args, Stream fd) { #if (VERBOSE_DEBUG) DebugOutput("Inside AddSubkeyHandler(..)"); #endif PgpSubkeyOptions subkeyOptions = settings.subkeyOptions; string output = ""; if (args != null) { if (args.Equals("keyedit.prompt") && !subkeyOptions.cmdSend) { // send command subkeyOptions.cmdSend = true; output = "addkey"; #if (VERBOSE_DEBUG) DebugOutput("End keygen.algo."); #endif return ToU8(output); } if (args.Equals("keygen.algo")) { /* Gnupg's configuration mode needs be set to "expert" * in order to specify customized DSA or RSA subkeys. */ settings.subkeyalgoquestion++; output = ((int)subkeyOptions.Algorithm).ToString(); // GPG IS NOT IN EXPERT MODE! if (settings.subkeyalgoquestion > 1) { #if (VERBOSE_DEBUG) DebugOutput("End keygen.algo."); #endif return ToU8("2"); } #if (VERBOSE_DEBUG) DebugOutput("End keygen.algo."); #endif return ToU8(output); } if (args.Equals("keygen.flags")) { // Auth is NOT enabled by default if ((subkeyOptions.Capability & AlgorithmCapability.CanAuth) == AlgorithmCapability.CanAuth && ((settings.subkeycapability & AlgorithmCapability.CanAuth) != AlgorithmCapability.CanAuth)) { settings.subkeycapability |= AlgorithmCapability.CanAuth; output = "A"; } // Sign is enabled by default! else if ((subkeyOptions.Capability & AlgorithmCapability.CanSign) != AlgorithmCapability.CanSign && ((settings.subkeycapability & AlgorithmCapability.CanSign) != AlgorithmCapability.CanSign)) { settings.subkeycapability |= AlgorithmCapability.CanSign; // save, that we have checked "Sign" flag output = "S"; } // Encrypt is enabled by default! else if ((subkeyOptions.Capability & AlgorithmCapability.CanEncrypt) != AlgorithmCapability.CanEncrypt && ((settings.subkeycapability & AlgorithmCapability.CanEncrypt) != AlgorithmCapability.CanEncrypt)) { settings.subkeycapability |= AlgorithmCapability.CanEncrypt; // save, that we have checked "Encrypt" flag output = "E"; } else // all flags specified output = "Q"; #if (VERBOSE_DEBUG) DebugOutput("End keygen.flags."); #endif return ToU8(output); } if (args.Equals("keygen.size")) { output = subkeyOptions.KeyLength.ToString(); #if (VERBOSE_DEBUG) DebugOutput("End keygen.size."); #endif return ToU8(output); } if (args.Equals("keygen.valid")) { if (subkeyOptions.IsInfinitely || (subkeyOptions.ExpirationDate.CompareTo(DateTime.Now) < 0)) output = "0"; else output = (subkeyOptions.ExpirationDate - DateTime.Now).Days.ToString(); #if (VERBOSE_DEBUG) DebugOutput("End keygen.valid."); #endif return ToU8(output); } if (args.Equals("keyedit.prompt")) { if (settings.subkeyalgoquestion > 1) /* Do not save the new created subkey because the user * requested a customized subkey but GnuPG was not in * "Expert" mode. */ output = "quit"; else output = "save"; #if (VERBOSE_DEBUG) DebugOutput("End --edit-key session."); #endif return ToU8(output); } } #if (VERBOSE_DEBUG) DebugOutput("End - WITH BYTE[0]"); #endif return new byte[0]; }
private byte[] DeleteSignatureHandler(KeyEditStatusCode status, string args, Stream fd) { PgpDeleteSignatureOptions delsigOptions = settings.delsigOptions; string output = ""; if (args != null) { if (args.Equals("keyedit.prompt") && !delsigOptions.cmdSend) { if (!delsigOptions.uidSend) { // send uid number delsigOptions.uidSend = true; output = "uid " + delsigOptions.SelectedUid.ToString(); return ToU8(output); } // send command delsigOptions.cmdSend = true; output = "delsig"; return ToU8(output); } if (args.Equals("keyedit.delsig.unknown") || args.Equals("keyedit.delsig.valid")) { if (delsigOptions.SelectedSignatures == null) { output = "Y"; } else { delsigOptions.ndeletenum++; if (Array.Exists<int>(delsigOptions.SelectedSignatures, delegate(int v) { return (v == delsigOptions.ndeletenum); })) { output = "Y"; } else { output = "N"; } } return ToU8(output); } if (args.Equals("keyedit.delsig.selfsig")) { if (delsigOptions.DeleteSelfSignature) output = "Y"; else output = "N"; return ToU8(output); } if (args.Equals("keyedit.prompt") && delsigOptions.cmdSend) { output = "save"; return ToU8(output); } } return new byte[0]; }
protected override int KeyEditCallback(IntPtr handle, KeyEditStatusCode status, string args, Stream fd) { KeyEditOp op = (KeyEditOp)handle; byte[] output = null; bool runhandler = true; #if (VERBOSE_DEBUG) DebugOutput("Callback op=" + op.ToString() + " status=" + status.ToString() + " args=" + args); #endif // Ignore ACK calls if (status == KeyEditStatusCode.GotIt && args == null && fd == null) runhandler = false; // actions that are equal in all key editing queries - except passphrase changes if (op != KeyEditOp.Passphrase) { switch (status) { case KeyEditStatusCode.GoodPassphrase: settings.passSettings.PassphrasePrevWasBad = false; output = new byte[0]; runhandler = false; break; } if (args != null) { switch (status) { case KeyEditStatusCode.UserIdHint: settings.passSettings.PassphraseUserIdHint = args; output = new byte[0]; runhandler = false; break; case KeyEditStatusCode.NeedPassphrase: settings.passSettings.PassphraseInfo = args; output = new byte[0]; runhandler = false; break; case KeyEditStatusCode.MissingPassphrase: case KeyEditStatusCode.BadPassphrase: settings.passSettings.PassphrasePrevWasBad = true; output = new byte[0]; runhandler = false; break; case KeyEditStatusCode.GetHidden: if (args.Equals("passphrase.enter")) { char[] passphrase = null; /* "passphrase.enter" appears if the context has no passphrase * callback function specified. */ if (settings.passSettings.PassphraseFunction != null && fd != null && settings.passSettings.PassphraseLastResult != PassphraseResult.Canceled) { settings.passSettings.PassphraseLastResult = settings.passSettings.PassphraseFunction( null, new PassphraseInfo(IntPtr.Zero, settings.passSettings.PassphraseUserIdHint, settings.passSettings.PassphraseInfo,settings.passSettings.PassphrasePrevWasBad), ref passphrase); if (passphrase != null) { byte[] p = Gpgme.ConvertCharArrayToUTF8(passphrase, 0); fd.Write(p, 0, p.Length); int i; // try to clear passphrase in memory for (i = 0; i < p.Length; i++) p[i] = 0; for (i = 0; i < passphrase.Length; i++) passphrase[i] = '\0'; } } else if (settings.passSettings.Passphrase != null && fd != null) { byte[] p = Gpgme.ConvertCharArrayToUTF8( settings.passSettings.Passphrase, 0); fd.Write(p, 0, p.Length); int i; // try to clear passphrase in memory for (i = 0; i < p.Length; i++) p[i] = 0; } else { // No password or password callback function specified! fd.Write(new byte[1] { 0 }, 0, 1); } output = new byte[0]; // confirm password (send \n) runhandler = false; } break; } } } if (runhandler) { #if (VERBOSE_DEBUG) DebugOutput("Run handler " + op.ToString()); #endif switch (op) { case KeyEditOp.Signature: output = SignHandler(status, args, fd); break; case KeyEditOp.Passphrase: output = PassphraseHandler(status, args, fd); if (output == null && settings.passOptions.aborthandler) return 1; // abort break; case KeyEditOp.RevokeSignature: output = RevokeSignatureHandler(status, args, fd); break; case KeyEditOp.DeleteSignature: output = DeleteSignatureHandler(status, args, fd); break; case KeyEditOp.EnableDisable: output = EnableDisableHandler(status, args, fd); break; case KeyEditOp.Trust: output = TrustHandler(status, args, fd); break; case KeyEditOp.AddSubkey: output = AddSubkeyHandler(status, args, fd); break; case KeyEditOp.Expire: output = ExpireHandler(status, args, fd); break; } #if (VERBOSE_DEBUG) DebugOutput("Handler " + op.ToString() + " finished."); #endif } if (output != null && fd != null) { #if (VERBOSE_DEBUG) DebugOutput(output); #endif fd.Write(output, 0, output.Length); fd.Flush(); fd.Write(new byte[] { (byte)'\n' }, 0, 1); fd.Flush(); } return 0; }
private byte[] TrustHandler(KeyEditStatusCode status, string args, Stream fd) { PgpTrustOptions trustOptions = settings.trustOptions; string output = ""; if (args != null) { if (args.Equals("keyedit.prompt")) { if (!trustOptions.cmdSend) { output = "trust"; trustOptions.cmdSend = true; } else { output = "quit"; } return ToU8(output); } if (args.Equals("edit_ownertrust.set_ultimate.okay")) { output = "Y"; return ToU8(output); } if (args.Equals("edit_ownertrust.value")) { output = ((int)trustOptions.trust).ToString(); return ToU8(output); } } return new byte[0]; }
private byte[] SignHandler(KeyEditStatusCode status, string args, Stream fd) { PgpSignatureOptions sigOptions = settings.sigOptions; string output = ""; if (args != null) { if (status == KeyEditStatusCode.AlreadySigned) throw new AlreadySignedException(args); // specify the uids that shall be signed if (args.Equals("keyedit.prompt") && !sigOptions.cmdSend && sigOptions.nUid == 0) { // do we want to specify the uids that we want to sign? if (sigOptions.SelectedUids != null && sigOptions.SelectedUids.Length > 0) sigOptions.signAllUids = false; else sigOptions.signAllUids = true; } if (args.Equals("keyedit.prompt") && (!sigOptions.signAllUids) && sigOptions.nUid < sigOptions.SelectedUids.Length) { output = "uid " + sigOptions.SelectedUids[sigOptions.nUid++]; return ToU8(output); } if (args.Equals("keyedit.prompt") && !sigOptions.cmdSend) { StringBuilder sb = new StringBuilder(); if ((sigOptions.Type & PgpSignatureType.NonExportable) == PgpSignatureType.NonExportable) sb.Append("l"); if ((sigOptions.Type & PgpSignatureType.Trust) == PgpSignatureType.Trust) sb.Append("t"); if ((sigOptions.Type & PgpSignatureType.NonRevocable) == PgpSignatureType.NonRevocable) sb.Append("nr"); output = sb.ToString() + "sign"; // mark that the operation command has been sent sigOptions.cmdSend = true; return ToU8(output); } if (args.Equals("sign_uid.class")) { output = ((int)sigOptions.Class).ToString(); return ToU8(output); } if (args.Equals("sign_uid.expire")) { output = sigOptions.IsInfinitely ? "N" : "Y"; return ToU8(output); } if (args.Equals("siggen.valid")) { output = sigOptions.GetExpirationDate(); return ToU8(output); } if (args.Equals("trustsig_prompt.trust_value")) { output = ((int)sigOptions.TrustLevel).ToString(); return ToU8(output); } if (args.Equals("trustsig_prompt.trust_depth")) { output = sigOptions.TrustDepth.ToString(); return ToU8(output); } if (args.Equals("trustsig_prompt.trust_regexp")) { output = sigOptions.TrustRegexp; if (output == null) output = ""; return Gpgme.ConvertCharArrayAnsi(output.ToCharArray()); } if (args.Equals("sign_uid.local_promote_okay")) { output = sigOptions.LocalPromoteOkay ? "Y" : "N"; return ToU8(output); } if (args.Equals("sign_uid.okay")) { output = "Y"; // Really sign? (y/N) return ToU8(output); } if (args.Equals("keyedit.sign_all.okay")) { if (sigOptions.signAllUids) // Really sign all user IDs? (y/N) { output = "Y"; } else { output = "N"; } return ToU8(output); } if (args.Equals("keyedit.prompt")) { if (!sigOptions.forceQuit) { output = "save"; sigOptions.forceQuit = true; } else output = "quit"; return ToU8(output); } if (args.Equals("keyedit.save.okay")) { output = "Y"; // Save changes? (y/N) return ToU8(output); } // .. unknown question } return new byte[0]; }
private byte[] RevokeSignatureHandler(KeyEditStatusCode status, string args, Stream fd) { PgpRevokeSignatureOptions revsigOptions = settings.revsigOptions; string output = ""; if (args != null) { // specify the uids from that the signature shall be revoked if (args.Equals("keyedit.prompt") && !revsigOptions.uidSend) { revsigOptions.uidSend = true; output = "uid " + revsigOptions.SelectedUid.ToString(); return ToU8(output); } if (args.Equals("keyedit.prompt") && !revsigOptions.cmdSend) { revsigOptions.cmdSend = true; output = "revsig"; return ToU8(output); } if (args.Equals("ask_revoke_sig.one") || args.Equals("ask_revoke_sig.expired")) { revsigOptions.nrevokenum++; // the user can specify his signatures that shall be revoked if (Array.Exists<int>(revsigOptions.SelectedSignatures, delegate(int v) { return (v == revsigOptions.nrevokenum); })) { output = "Y"; } else { output = "N"; } return ToU8(output); } if (args.Equals("ask_revoke_sig.okay") || args.Equals("ask_revocation_reason.okay")) { output = "Y"; // we can revoke all signatures that were signed by private key from our store return ToU8(output); } if (args.Equals("ask_revocation_reason.code")) { output = ((int)revsigOptions.ReasonCode).ToString(); return ToU8(output); } if (args.Equals("ask_revocation_reason.text")) { if (revsigOptions.reasonTxt == null) output = ""; else { if (revsigOptions.nreasonTxt >= revsigOptions.reasonTxt.Length) { if (libgpgme.IsWindows) output = ""; else output = " "; } else output = revsigOptions.reasonTxt[revsigOptions.nreasonTxt++]; } return ToU8(output); } if (args.Equals("keyedit.prompt") && revsigOptions.cmdSend) { output = "save"; return ToU8(output); } } return new byte[0]; }
private byte[] PassphraseHandler(KeyEditStatusCode status, string args, Stream fd) { PgpPassphraseOptions passOptions = settings.passOptions; string output = ""; int i; switch (status) { case KeyEditStatusCode.MissingPassphrase: passOptions.missingpasswd = true; // empty passphrase passOptions.emptypasswdcount++; if (passOptions.missingpasswd && passOptions.emptypasswdcount >= PgpPassphraseOptions.MAX_PASSWD_COUNT) { passOptions.aborthandler = true; return null; } break; case KeyEditStatusCode.GoodPassphrase: if (passOptions.needoldpw) // old password has been entered correctly passOptions.needoldpw = false; return null; case KeyEditStatusCode.NeedPassphraseSym: if (passOptions.needoldpw) // old password has been entered already passOptions.needoldpw = false; return null; } if (args != null) { if (args.Equals("keyedit.prompt") && !passOptions.passphraseSendCmd) { passOptions.passphraseSendCmd = true; output = "passwd"; return ToU8(output); } if (args != null) { switch (status) { case KeyEditStatusCode.UserIdHint: settings.passSettings.PassphraseUserIdHint = args; return new byte[0]; case KeyEditStatusCode.NeedPassphrase: settings.passSettings.PassphraseInfo = args; return new byte[0]; case KeyEditStatusCode.MissingPassphrase: case KeyEditStatusCode.BadPassphrase: settings.passSettings.PassphrasePrevWasBad = true; return new byte[0]; case KeyEditStatusCode.GetHidden: if (args.Equals("passphrase.enter")) { char[] passphrase = null; PassphraseDelegate passphraseFunc = null; if (passOptions.needoldpw) { // ask for old password passphraseFunc = passOptions.OldPassphraseCallback; if (passOptions.OldPassphrase != null) { passphrase = new char[passOptions.OldPassphrase.Length]; // TODO: can we trust Array.Copy? Array.Copy(passOptions.OldPassphrase, passphrase, passOptions.OldPassphrase.Length); } } else { // ask for new password passphraseFunc = passOptions.NewPassphraseCallback; if (passOptions.NewPassphrase != null) { passphrase = new char[passOptions.NewPassphrase.Length]; // TODO: can we trust Array.Copy? Array.Copy(passOptions.OldPassphrase, passphrase, passOptions.NewPassphrase.Length); } } if (passphraseFunc != null && fd != null && settings.passSettings.PassphraseLastResult != PassphraseResult.Canceled) { #if (VERBOSE_DEBUG) DebugOutput("Calling passphrase callback function.. "); #endif // run callback function settings.passSettings.PassphraseLastResult = passphraseFunc( null, new PassphraseInfo(IntPtr.Zero, settings.passSettings.PassphraseUserIdHint, settings.passSettings.PassphraseInfo, settings.passSettings.PassphrasePrevWasBad), ref passphrase); } if (passphrase != null) { if (fd != null) { byte[] p = Gpgme.ConvertCharArrayToUTF8(passphrase, 0); fd.Write(p, 0, p.Length); // try to clear passphrase in memory for (i = 0; i < p.Length; i++) p[i] = 0; } // try to clear for (i = 0; i < passphrase.Length; i++) passphrase[i] = '\0'; } } break; } if (args.Equals("change_passwd.empty.okay")) { output = (passOptions.EmptyOkay) ? "Y" : "N"; return ToU8(output); } if (args.Equals("keyedit.prompt")) { output = "save"; return ToU8(output); } } } return new byte[0]; }