diff options
author | Damien Miller <djm@mindrot.org> | 2000-10-14 16:23:11 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-10-14 16:23:11 +1100 |
commit | 874d77bb134a21a5cf625956b60173376a993ba8 (patch) | |
tree | 93dd73b2ff1fbf0ad5f3978a2c4e0d8438a0bf7c /cli.c | |
parent | 89d9796fbedef4eed6956a2c095c7cc25330c28d (diff) |
- (djm) Big OpenBSD sync:
- markus@cvs.openbsd.org 2000/09/30 10:27:44
[log.c]
allow loglevel debug
- markus@cvs.openbsd.org 2000/10/03 11:59:57
[packet.c]
hmac->mac
- markus@cvs.openbsd.org 2000/10/03 12:03:03
[auth-krb4.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth1.c]
move fake-auth from auth1.c to individual auth methods, disables s/key in
debug-msg
- markus@cvs.openbsd.org 2000/10/03 12:16:48
ssh.c
do not resolve canonname, i have no idea why this was added oin ossh
- markus@cvs.openbsd.org 2000/10/09 15:30:44
ssh-keygen.1 ssh-keygen.c
-X now reads private ssh.com DSA keys, too.
- markus@cvs.openbsd.org 2000/10/09 15:32:34
auth-options.c
clear options on every call.
- markus@cvs.openbsd.org 2000/10/09 15:51:00
authfd.c authfd.h
interop with ssh-agent2, from <res@shore.net>
- markus@cvs.openbsd.org 2000/10/10 14:20:45
compat.c
use rexexp for version string matching
- provos@cvs.openbsd.org 2000/10/10 22:02:18
[kex.c kex.h myproposal.h ssh.h ssh2.h sshconnect2.c sshd.c dh.c dh.h]
First rough implementation of the diffie-hellman group exchange. The
client can ask the server for bigger groups to perform the diffie-hellman
in, thus increasing the attack complexity when using ciphers with longer
keys. University of Windsor provided network, T the company.
- markus@cvs.openbsd.org 2000/10/11 13:59:52
[auth-rsa.c auth2.c]
clear auth options unless auth sucessfull
- markus@cvs.openbsd.org 2000/10/11 14:00:27
[auth-options.h]
clear auth options unless auth sucessfull
- markus@cvs.openbsd.org 2000/10/11 14:03:27
[scp.1 scp.c]
support 'scp -o' with help from mouring@pconline.com
- markus@cvs.openbsd.org 2000/10/11 14:11:35
[dh.c]
Wall
- markus@cvs.openbsd.org 2000/10/11 14:14:40
[auth.h auth2.c readconf.c readconf.h readpass.c servconf.c servconf.h]
[ssh.h sshconnect2.c sshd_config auth2-skey.c cli.c cli.h]
add support for s/key (kbd-interactive) to ssh2, based on work by
mkiernan@avantgo.com and me
- markus@cvs.openbsd.org 2000/10/11 14:27:24
[auth.c auth1.c auth2.c authfile.c cipher.c cipher.h kex.c kex.h]
[myproposal.h packet.c readconf.c session.c ssh.c ssh.h sshconnect1.c]
[sshconnect2.c sshd.c]
new cipher framework
- markus@cvs.openbsd.org 2000/10/11 14:45:21
[cipher.c]
remove DES
- markus@cvs.openbsd.org 2000/10/12 03:59:20
[cipher.c cipher.h sshconnect1.c sshconnect2.c sshd.c]
enable DES in SSH-1 clients only
- markus@cvs.openbsd.org 2000/10/12 08:21:13
[kex.h packet.c]
remove unused
- markus@cvs.openbsd.org 2000/10/13 12:34:46
[sshd.c]
Kludge for F-Secure Macintosh < 1.0.2; appro@fy.chalmers.se
- markus@cvs.openbsd.org 2000/10/13 12:59:15
[cipher.c cipher.h myproposal.h rijndael.c rijndael.h]
rijndael/aes support
- markus@cvs.openbsd.org 2000/10/13 13:10:54
[sshd.8]
more info about -V
- markus@cvs.openbsd.org 2000/10/13 13:12:02
[myproposal.h]
prefer no compression
Diffstat (limited to 'cli.c')
-rw-r--r-- | cli.c | 195 |
1 files changed, 195 insertions, 0 deletions
@@ -0,0 +1,195 @@ +#include "includes.h" +RCSID("$Id: cli.c,v 1.1 2000/10/14 05:23:12 djm Exp $"); + +#include "xmalloc.h" +#include "ssh.h" + +static int cli_input = -1; +static int cli_output = -1; +static int cli_from_stdin = 0; + +sigset_t oset; +sigset_t nset; +struct sigaction nsa; +struct sigaction osa; +struct termios ntio; +struct termios otio; +int echo_modified; + +volatile int intr; + +static int +cli_open(int from_stdin) +{ + if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin) + return 1; + + if (from_stdin) { + if (!cli_from_stdin && cli_input >= 0) { + (void)close(cli_input); + } + cli_input = STDIN_FILENO; + cli_output = STDERR_FILENO; + } else { + cli_input = cli_output = open("/dev/tty", O_RDWR); + if (cli_input < 0) + fatal("You have no controlling tty. Cannot read passphrase."); + } + + cli_from_stdin = from_stdin; + + return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin; +} + +static void +cli_close() +{ + if (!cli_from_stdin && cli_input >= 0) + close(cli_input); + cli_input = -1; + cli_output = -1; + cli_from_stdin = 0; + return; +} + +void +intrcatch() +{ + intr = 1; +} + +static void +cli_echo_disable() +{ + sigemptyset(&nset); + sigaddset(&nset, SIGTSTP); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + + intr = 0; + + memset(&nsa, 0, sizeof(nsa)); + nsa.sa_handler = intrcatch; + (void) sigaction(SIGINT, &nsa, &osa); + + echo_modified = 0; + if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) { + echo_modified = 1; + ntio = otio; + ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + (void) tcsetattr(cli_input, TCSANOW, &ntio); + } + return; +} + +static void +cli_echo_restore() +{ + if (echo_modified != 0) { + tcsetattr(cli_input, TCSANOW, &otio); + echo_modified = 0; + } + + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) sigaction(SIGINT, &osa, NULL); + + if (intr != 0) { + kill(getpid(), SIGINT); + sigemptyset(&nset); + /* XXX tty has not neccessarily drained by now? */ + sigsuspend(&nset); + intr = 0; + } + return; +} + +static int +cli_read(char* buf, int size, int echo) +{ + char ch = 0; + int i = 0; + + if (!echo) + cli_echo_disable(); + + while (ch != '\n') { + if (read(cli_input, &ch, 1) != 1) + break; + if (ch == '\n' || intr != 0) + break; + if (i < size) + buf[i++] = ch; + } + buf[i] = '\0'; + + if (!echo) + cli_echo_restore(); + if (!intr && !echo) + (void) write(cli_output, "\n", 1); + return i; +} + +static int +cli_write(char* buf, int size) +{ + int i, len, pos, ret = 0; + char *output, *p; + + output = xmalloc(4*size); + for (p = output, i = 0; i < size; i++) { + if (buf[i] == '\n') + *p++ = buf[i]; + else + p = vis(p, buf[i], 0, 0); + } + len = p - output; + + for (pos = 0; pos < len; pos += ret) { + ret = write(cli_output, output + pos, len - pos); + if (ret == -1) + return -1; + } + return 0; +} + +/* + * Presents a prompt and returns the response allocated with xmalloc(). + * Uses /dev/tty or stdin/out depending on arg. Optionally disables echo + * of response depending on arg. Tries to ensure that no other userland + * buffer is storing the response. + */ +char* +cli_read_passphrase(char* prompt, int from_stdin, int echo_enable) +{ + char buf[BUFSIZ]; + char* p; + + if (!cli_open(from_stdin)) + fatal("Cannot read passphrase."); + + fflush(stdout); + + cli_write(prompt, strlen(prompt)); + cli_read(buf, sizeof buf, echo_enable); + + cli_close(); + + p = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return (p); +} + +char* +cli_prompt(char* prompt, int echo_enable) +{ + return cli_read_passphrase(prompt, 0, echo_enable); +} + +void +cli_mesg(char* mesg) +{ + cli_open(0); + cli_write(mesg, strlen(mesg)); + cli_write("\n", strlen("\n")); + cli_close(); + return; +} |