summaryrefslogtreecommitdiff
path: root/ssh-add.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 11:54:57 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 11:54:57 +1100
commit5428f646ad32da88ddd04a8c287d595524674fbf (patch)
treecc1f1e5d7852e1f44d41077f776abf7dab7ac06d /ssh-add.c
parent9072e1889648988da38b7b81bce95291c1dc3a23 (diff)
- More reformatting merged from OpenBSD CVS
- Merged OpenBSD CVS changes: - [channels.c] report from mrwizard@psu.edu via djm@ibs.com.au - [channels.c] set SO_REUSEADDR and SO_LINGER for forwarded ports. chip@valinux.com via damien@ibs.com.au - [nchan.c] it's not an error() if shutdown_write failes in nchan. - [readconf.c] remove dead #ifdef-0-code - [readconf.c servconf.c] strcasecmp instead of tolower - [scp.c] progress meter overflow fix from damien@ibs.com.au - [ssh-add.1 ssh-add.c] SSH_ASKPASS support - [ssh.1 ssh.c] postpone fork_after_authentication until command execution, request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au plus: use daemon() for backgrounding
Diffstat (limited to 'ssh-add.c')
-rw-r--r--ssh-add.c167
1 files changed, 59 insertions, 108 deletions
diff --git a/ssh-add.c b/ssh-add.c
index f94dcdab..711ae126 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -7,7 +7,7 @@
*/
#include "includes.h"
-RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $");
+RCSID("$Id: ssh-add.c,v 1.14 1999/11/25 00:54:59 damien Exp $");
#include "rsa.h"
#include "ssh.h"
@@ -15,10 +15,6 @@ RCSID("$Id: ssh-add.c,v 1.13 1999/11/24 13:26:22 damien Exp $");
#include "authfd.h"
#include "fingerprint.h"
-#ifdef USE_EXTERNAL_ASKPASS
-int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment);
-#endif /* USE_EXTERNAL_ASKPASS */
-
#ifdef HAVE___PROGNAME
extern char *__progname;
#else /* HAVE___PROGNAME */
@@ -54,13 +50,53 @@ delete_all(AuthenticationConnection *ac)
fprintf(stderr, "Failed to remove all identitities.\n");
}
+char *
+ssh_askpass(char *askpass, char *msg)
+{
+ pid_t pid;
+ size_t len;
+ char *nl, *pass;
+ int p[2], status;
+ char buf[1024];
+
+ if (askpass == NULL)
+ fatal("internal error: askpass undefined");
+ if (pipe(p) < 0)
+ fatal("ssh_askpass: pipe: %s", strerror(errno));
+ if ((pid = fork()) < 0)
+ fatal("ssh_askpass: fork: %s", strerror(errno));
+ if (pid == 0) {
+ close(p[0]);
+ if (dup2(p[1], STDOUT_FILENO) < 0)
+ fatal("ssh_askpass: dup2: %s", strerror(errno));
+ execlp(askpass, askpass, msg, (char *) 0);
+ fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
+ }
+ close(p[1]);
+ len = read(p[0], buf, sizeof buf);
+ close(p[0]);
+ while (waitpid(pid, &status, 0) < 0)
+ if (errno != EINTR)
+ break;
+ if (len <= 1)
+ return xstrdup("");
+ nl = strchr(buf, '\n');
+ if (nl)
+ *nl = '\0';
+ pass = xstrdup(buf);
+ memset(buf, 0, sizeof(buf));
+ return pass;
+}
+
void
add_file(AuthenticationConnection *ac, const char *filename)
{
RSA *key;
RSA *public_key;
- char *saved_comment, *comment;
+ char *saved_comment, *comment, *askpass = NULL;
+ char buf[1024], msg[1024];
int success;
+ int interactive = isatty(STDIN_FILENO);
key = RSA_new();
public_key = RSA_new();
@@ -70,29 +106,26 @@ add_file(AuthenticationConnection *ac, const char *filename)
}
RSA_free(public_key);
+ if (!interactive && getenv("DISPLAY"))
+ askpass = getenv("SSH_ASKPASS");
+
/* At first, try empty passphrase */
success = load_private_key(filename, "", key, &comment);
if (!success) {
- printf("Need passphrase for %s (%s).\n", filename, saved_comment);
- if (!isatty(STDIN_FILENO)) {
-#ifdef USE_EXTERNAL_ASKPASS
- int prompts = 3;
- while (prompts && !success) {
- success = askpass(filename, key, saved_comment, &comment);
- prompts--;
- }
- if (!success) {
- xfree(saved_comment);
- return;
- }
-#else /* !USE_EXTERNAL_ASKPASS */
- xfree(saved_comment);
- return;
-#endif /* USE_EXTERNAL_ASKPASS */
+ printf("Need passphrase for %.200s\n", filename);
+ if (!interactive && askpass == NULL) {
+ xfree(saved_comment);
+ return;
}
-
- while (!success) {
- char *pass = read_passphrase("Enter passphrase: ", 1);
+ snprintf(msg, sizeof msg, "Enter passphrase for %.200s", saved_comment);
+ for (;;) {
+ char *pass;
+ if (interactive) {
+ snprintf(buf, sizeof buf, "%s: ", msg);
+ pass = read_passphrase(buf, 1);
+ } else {
+ pass = ssh_askpass(askpass, msg);
+ }
if (strcmp(pass, "") == 0) {
xfree(pass);
xfree(saved_comment);
@@ -103,7 +136,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
xfree(pass);
if (success)
break;
- printf("Bad passphrase.\n");
+ strlcpy(msg, "Bad passphrase, try again", sizeof msg);
}
}
xfree(saved_comment);
@@ -222,85 +255,3 @@ main(int argc, char **argv)
ssh_close_authentication_connection(ac);
exit(0);
}
-
-#ifdef USE_EXTERNAL_ASKPASS
-int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment)
-{
- int pipes[2];
- char buf[1024];
- int tmp;
- pid_t child;
- FILE *pipef;
-
- /* Check that we are X11-capable */
- if (getenv("DISPLAY") == NULL)
- exit(1);
-
- if (pipe(pipes) == -1) {
- fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
- exit(1);
- }
-
- if (fflush(NULL) == EOF) {
- fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
- exit(1);
- }
-
- child = fork();
- if (child == -1) {
- fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
- exit(1);
- }
-
- if (child == 0) {
- /* In child */
-
- close(pipes[0]);
- if (dup2(pipes[1], 1) ==-1) {
- fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
- exit(1);
- }
-
- tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s", saved_comment);
- /* skip the prompt if it won't fit */
- if ((tmp < 0) || (tmp >= sizeof(buf)))
- tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
- else
- tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
-
- /* Shouldn't get this far */
- fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno));
- exit(1);
- }
-
- /* In parent */
- close(pipes[1]);
-
- if ((pipef = fdopen(pipes[0], "r")) == NULL) {
- fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
- exit(1);
- }
-
- /* Read passphrase back from child, abort if none presented */
- if(fgets(buf, sizeof(buf), pipef) == NULL)
- exit(1);
-
- fclose(pipef);
-
- if (strchr(buf, '\n'))
- *strchr(buf, '\n') = 0;
-
- if (waitpid(child, NULL, 0) == -1) {
- fprintf(stderr, "Waiting for child failed: %s\n",
- strerror(errno));
- exit(1);
- }
-
- /* Try password as it was presented */
- tmp = load_private_key(filename, buf, key, comment);
-
- memset(buf, 0, sizeof(buf));
-
- return(tmp);
-}
-#endif /* USE_EXTERNAL_ASKPASS */