Commit caa1a65b authored by Niels Möller's avatar Niels Möller
Browse files

(unix_read_password): Split off...

(read_password): New function, reads password and doesn't free
prompt.
(unix_dialog): New function.

Rev: src/unix_interact.c:1.26
parent a96bd2c8
...@@ -53,8 +53,9 @@ ...@@ -53,8 +53,9 @@
#include "unix_interact.c.x" #include "unix_interact.c.x"
/* Depends on the tty being line buffered */ /* Depends on the tty being line buffered. FIXME: Doesn't distinguish
static int between errors, empty input, and EOF. */
static uint32_t
read_line(int fd, uint32_t size, uint8_t *buffer) read_line(int fd, uint32_t size, uint8_t *buffer)
{ {
uint32_t i = 0; uint32_t i = 0;
...@@ -109,7 +110,7 @@ read_line(int fd, uint32_t size, uint8_t *buffer) ...@@ -109,7 +110,7 @@ read_line(int fd, uint32_t size, uint8_t *buffer)
uint32_t j; uint32_t j;
for (j = 0; j < (unsigned) res; j++) for (j = 0; j < (unsigned) res; j++)
if (b[j] == '\n') if (b[j] == '\n')
return res; return size;
} }
} }
#undef BUFSIZE #undef BUFSIZE
...@@ -176,24 +177,18 @@ unix_is_tty(struct interact *s) ...@@ -176,24 +177,18 @@ unix_is_tty(struct interact *s)
/* FIXME: Rewrite to operate on tty_fd. */ /* FIXME: Rewrite to operate on tty_fd. */
static struct lsh_string * static struct lsh_string *
unix_read_password(struct interact *s, read_password(struct unix_interact *self,
uint32_t max_length UNUSED, const struct lsh_string *prompt)
const struct lsh_string *prompt)
{ {
CAST(unix_interact, self, s);
trace("unix_interact.c:unix_read_password\n");
if (self->askpass) if (self->askpass)
{ {
const char *argv[3]; const char *argv[3];
struct lsh_string *password;
int null = open("/dev/null", O_RDONLY); int null = open("/dev/null", O_RDONLY);
if (null < 0) if (null < 0)
{ {
werror("Failed to open /dev/null!\n"); werror("Failed to open /dev/null!\n");
lsh_string_free(prompt);
return NULL; return NULL;
} }
...@@ -203,7 +198,6 @@ unix_read_password(struct interact *s, ...@@ -203,7 +198,6 @@ unix_read_password(struct interact *s,
if (!argv[1]) if (!argv[1])
{ {
close(null); close(null);
lsh_string_free(prompt);
return NULL; return NULL;
} }
...@@ -212,11 +206,7 @@ unix_read_password(struct interact *s, ...@@ -212,11 +206,7 @@ unix_read_password(struct interact *s,
trace("unix_interact.c: spawning askpass program `%z'\n", trace("unix_interact.c: spawning askpass program `%z'\n",
self->askpass); self->askpass);
password = lsh_popen_read(self->askpass, argv, null, 100); return lsh_popen_read(self->askpass, argv, null, 100);
lsh_string_free(prompt);
return password;
} }
else else
{ {
...@@ -226,22 +216,15 @@ unix_read_password(struct interact *s, ...@@ -226,22 +216,15 @@ unix_read_password(struct interact *s,
const char *cprompt; const char *cprompt;
if (!IS_TTY(self) || quiet_flag) if (!IS_TTY(self) || quiet_flag)
{ return NULL;
lsh_string_free(prompt);
return NULL;
}
cprompt = lsh_get_cstring(prompt); cprompt = lsh_get_cstring(prompt);
if (!cprompt) if (!cprompt)
{ return NULL;
lsh_string_free(prompt);
return NULL;
}
/* NOTE: This function uses a static buffer. */ /* NOTE: This function uses a static buffer. */
password = getpass(cprompt); password = getpass(cprompt);
lsh_string_free(prompt);
if (!password) if (!password)
return NULL; return NULL;
...@@ -249,6 +232,22 @@ unix_read_password(struct interact *s, ...@@ -249,6 +232,22 @@ unix_read_password(struct interact *s,
} }
} }
static struct lsh_string *
unix_read_password(struct interact *s,
uint32_t max_length UNUSED,
const struct lsh_string *prompt)
{
CAST(unix_interact, self, s);
struct lsh_string *password;
trace("unix_interact.c:unix_read_password\n");
password = read_password(self, prompt);
lsh_string_free(prompt);
return password;
}
static void static void
unix_set_askpass(struct interact *s, unix_set_askpass(struct interact *s,
const char *askpass) const char *askpass)
...@@ -302,6 +301,51 @@ unix_yes_or_no(struct interact *s, ...@@ -302,6 +301,51 @@ unix_yes_or_no(struct interact *s,
} }
} }
/* The prompts are typically not trusted, but it's the callers
responsibility to sanity check them. */
static int
unix_dialog(struct interact *s,
const struct lsh_string *instruction,
const struct interact_dialog *dialog)
{
#define DIALOG_BUFSIZE 150
CAST(unix_interact, self, s);
const struct exception *e;
unsigned i;
e = write_raw(self->tty_fd, STRING_LD(instruction));
lsh_string_free(instruction);
if (e)
return 0;
for (i = 0; i < dialog->nprompt; i++)
{
struct lsh_string *prompt = dialog->prompt[i];
if (dialog->echo[i])
{
uint8_t buffer[DIALOG_BUFSIZE];
uint32_t length;
e = write_raw(self->tty_fd, STRING_LD(prompt));
if (e)
return 0;
length = read_line(self->tty_fd, DIALOG_BUFSIZE, buffer);
if (!length)
return 0;
dialog->response[i] = ssh_format("%ls", length, buffer);
}
else
{
if (!(dialog->response[i] = read_password(self, prompt)))
return 0;
}
}
return 1;
}
/* GABA: /* GABA:
(class (class
(name unix_termios) (name unix_termios)
...@@ -463,6 +507,7 @@ make_unix_interact(void) ...@@ -463,6 +507,7 @@ make_unix_interact(void)
self->super.read_password = unix_read_password; self->super.read_password = unix_read_password;
self->super.set_askpass = unix_set_askpass; self->super.set_askpass = unix_set_askpass;
self->super.yes_or_no = unix_yes_or_no; self->super.yes_or_no = unix_yes_or_no;
self->super.dialog = unix_dialog;
self->super.get_attributes = unix_get_attributes; self->super.get_attributes = unix_get_attributes;
self->super.set_attributes = unix_set_attributes; self->super.set_attributes = unix_set_attributes;
self->super.window_size = unix_window_size; self->super.window_size = unix_window_size;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment