Skip to content

Instantly share code, notes, and snippets.

@masiulaniec
Created May 24, 2012 17:07
Show Gist options
  • Save masiulaniec/2782828 to your computer and use it in GitHub Desktop.
Save masiulaniec/2782828 to your computer and use it in GitHub Desktop.
Lookup ssh(1) password in factotum(4)
diff --git a/misc.c b/misc.c
index a7a23dc..73a1741 100644
--- a/misc.c
+++ b/misc.c
@@ -712,6 +712,59 @@ tun_open(int tun, int mode)
#endif
}
+/*
+ * Query factotum(4) for the password. Return NULL if not found.
+ * Reuses SSH_ASKPASS code.
+ */
+char *
+factotum_rpc(const char *user, const char *server) {
+ char *odisplay, *oaskpass;
+ char *args, *password;
+ char *glue;
+
+ glue = getenv("SSH_FACTOTUM");
+ if (glue == NULL)
+ return NULL;
+
+ debug("Querying factotum: %s@%s", user, server);
+
+ /* preserve original environment */
+ oaskpass = getenv(SSH_ASKPASS_ENV);
+ odisplay = getenv("DISPLAY");
+
+ /* override */
+ if (setenv(SSH_ASKPASS_ENV, glue, 1) < 0) {
+ error("factotum_rpc: setenv: %s", strerror(errno));
+ exit(1);
+ }
+ if (setenv("DISPLAY", "factotum", 1) < 0) {
+ error("factotum_rpc: setenv: %s", strerror(errno));
+ exit(1);
+ }
+
+ /* make the call */
+ if (asprintf(&args, "%s@%s", user, server) < 0) {
+ error("factotum_rpc: asprintf: %s", strerror(errno));
+ exit(1);
+ }
+ password = read_passphrase(args, RP_USE_ASKPASS);
+ if (strcmp(password, "") == 0)
+ password = NULL;
+
+ /* restore original environment */
+ if (oaskpass)
+ setenv(SSH_ASKPASS_ENV, oaskpass, 1);
+ else
+ unsetenv(SSH_ASKPASS_ENV);
+ if (odisplay)
+ setenv(SSH_ASKPASS_ENV, odisplay, 1);
+ else
+ unsetenv("DISPLAY");
+
+ return password;
+}
+
+
void
sanitise_stdfd(void)
{
diff --git a/misc.h b/misc.h
index f3142a9..836a6a1 100644
--- a/misc.h
+++ b/misc.h
@@ -53,6 +53,7 @@ void replacearg(arglist *, u_int, char *, ...)
void freeargs(arglist *);
int tun_open(int, int);
+char *factotum_rpc(const char *, const char *);
/* Common definitions for ssh tunnel device forwarding */
#define SSH_TUNMODE_NO 0x00
diff --git a/sshconnect1.c b/sshconnect1.c
index fd07bbf..e2dcf8f 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -444,7 +444,7 @@ try_challenge_response_authentication(void)
* Tries to authenticate with plain passwd authentication.
*/
static int
-try_password_authentication(char *prompt)
+try_password_authentication(char *prompt, const char *user, const char *server)
{
int type, i;
char *password;
@@ -455,7 +455,9 @@ try_password_authentication(char *prompt)
for (i = 0; i < options.number_of_password_prompts; i++) {
if (i != 0)
error("Permission denied, please try again.");
- password = read_passphrase(prompt, 0);
+ password = factotum_rpc(user, server);
+ if (password == NULL)
+ password = read_passphrase(prompt, 0);
packet_start(SSH_CMSG_AUTH_PASSWORD);
ssh_put_password(password);
memset(password, 0, strlen(password));
@@ -741,7 +743,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
server_user, host);
- if (try_password_authentication(prompt))
+ if (try_password_authentication(prompt, server_user, host))
goto success;
}
/* All authentication methods have failed. Exit with an error message. */
diff --git a/sshconnect2.c b/sshconnect2.c
index c24b202..ea2b920 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -875,9 +875,12 @@ userauth_passwd(Authctxt *authctxt)
if (attempt != 1)
error("Permission denied, please try again.");
- snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
- authctxt->server_user, host);
- password = read_passphrase(prompt, 0);
+ password = factotum_rpc(authctxt->server_user, host);
+ if (password == NULL) {
+ snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
+ authctxt->server_user, host);
+ password = read_passphrase(prompt, 0);
+ }
packet_start(SSH2_MSG_USERAUTH_REQUEST);
packet_put_cstring(authctxt->server_user);
packet_put_cstring(authctxt->service);
@@ -989,9 +992,12 @@ jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
u_int secret_len;
BIGNUM *ret;
- snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
- authctxt->server_user, authctxt->host);
- password = read_passphrase(prompt, 0);
+ password = factotum_rpc(authctxt->server_user, authctxt->host);
+ if (password == NULL) {
+ snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
+ authctxt->server_user, authctxt->host);
+ password = read_passphrase(prompt, 0);
+ }
if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {
logit("Disabling %s authentication", authctxt->method->name);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment