core: Do not crash if CMS plaintext is ignored
[gpgme.git] / src / passwd.c
index 0ed54ba..6c03002 100644 (file)
@@ -14,7 +14,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with this program; if not, see <http://www.gnu.org/licenses/>.
+   License along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #if HAVE_CONFIG_H
@@ -30,6 +30,9 @@
 
 typedef struct
 {
+  /* The error code from a FAILURE status line or 0.  */
+  gpg_error_t failure_code;
+
   int success_seen;
   int error_seen;
 } *op_data_t;
@@ -56,7 +59,7 @@ parse_error (char *args)
       where = args;
     }
   else
-    return gpg_error (GPG_ERR_INV_ENGINE);
+    return trace_gpg_error (GPG_ERR_INV_ENGINE);
 
   err = atoi (which);
 
@@ -92,6 +95,10 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
       opd->success_seen = 1;
       break;
 
+    case GPGME_STATUS_FAILURE:
+      opd->failure_code = _gpgme_parse_failure (args);
+      break;
+
     case GPGME_STATUS_EOF:
       /* In case the OpenPGP engine does not properly implement the
          passwd command we won't get a success status back and thus we
@@ -102,6 +109,8 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
       if (ctx->protocol == GPGME_PROTOCOL_OpenPGP
           && !opd->error_seen && !opd->success_seen)
         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      else if (opd->failure_code)
+        err = opd->failure_code;
       break;
 
     default:
@@ -139,6 +148,14 @@ passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
 
   _gpgme_engine_set_status_handler (ctx->engine, passwd_status_handler, ctx);
 
+  if (ctx->passphrase_cb)
+    {
+      err = _gpgme_engine_set_command_handler
+        (ctx->engine, _gpgme_passphrase_command_handler, ctx);
+      if (err)
+        return err;
+    }
+
   return _gpgme_engine_op_passwd (ctx->engine, key, flags);
 }