Exit status on `ssh-add` failure
Damien Miller
djm at mindrot.org
Tue Jun 2 09:22:55 AEST 2026
On Mon, 1 Jun 2026, Wiktor Kwapisiewicz via openssh-unix-dev wrote:
> On 1.06.2026 10:35, Damien Miller wrote:
> > maybe it's time to change the behaviour?
>
> That would be most welcome, thank you!
>
> > diff --git a/ssh-add.c b/ssh-add.c
> > index 2788f7e..ca5d206 100644
> > --- a/ssh-add.c
> > +++ b/ssh-add.c
> > @@ -398,6 +398,7 @@ add_file(int agent_fd, const char *filename, int
> > key_only, int cert_only,
> > goto out;
> > }
> > + ret = -1; /* cert errors after here yield a nonzero exit status */
> > if (!sshkey_equal_public(cert, private)) {
> > error("Certificate %s does not match private key %s",
> > certpath, filename);
>
> I've tested this change on top of de97e5a44c88179b834939b84cd555249382de0e
> (current master) and it works fine. ssh-add fails successfully :)
>
> But now it seems to fail even on successful append of the cert...
>
> Based on the message I'm getting ("Certificate id_rsa-cert.pub (darren) add
> failed: communication with agent failed") I've moved that ret here:
>
> diff --git a/ssh-add.c b/ssh-add.c
> index 1e9eddf90..9248ef3b4 100644
> --- a/ssh-add.c
> +++ b/ssh-add.c
> @@ -433,6 +433,7 @@ add_file(int agent_fd, const char *filename, int key_only,
> int cert_only,
> dest_constraints, ndest_constraints)) != 0) {
> error_r(r, "Certificate %s (%s) add failed", certpath,
> private->cert->key_id);
> + ret = -1;
> goto out;
> }
> /* success */
>
> And now it seems to fail when adding the cert fails and succeed when it
> succeeds. I'm happy to test more patches in case there's a better way to solve
> this.
try this
diff --git a/ssh-add.c b/ssh-add.c
index 2788f7e..410277b 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -392,12 +392,15 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only,
/* Now try to add the certificate flavour too */
xasprintf(&certpath, "%s-cert.pub", filename);
if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) {
- if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT)
+ if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) {
+ ret = -1;
error_r(r, "Failed to load certificate \"%s\"",
certpath);
+ }
goto out;
}
+ ret = -1; /* cert errors after here yield a nonzero exit status */
if (!sshkey_equal_public(cert, private)) {
error("Certificate %s does not match private key %s",
certpath, filename);
@@ -429,6 +432,7 @@ add_file(int agent_fd, const char *filename, int key_only, int cert_only,
goto out;
}
/* success */
+ ret = 0;
if (!qflag) {
fprintf(stderr, "Certificate added: %s (%s)\n", certpath,
private->cert->key_id);
More information about the openssh-unix-dev
mailing list