Resolve conflicts and update for FreeBSD.
This commit is contained in:
parent
fe01acb846
commit
e8aafc91b5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=60576
@ -1,10 +1,11 @@
|
||||
$FreeBSD$
|
||||
$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $
|
||||
|
||||
howto:
|
||||
1) generate server key:
|
||||
$ ssh-keygen -d -f /etc/ssh_host_dsa_key -N ''
|
||||
$ ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N ''
|
||||
2) enable ssh2:
|
||||
server: add 'Protocol 2,1' to /etc/sshd_config
|
||||
server: add 'Protocol 2,1' to /etc/ssh/sshd_config
|
||||
client: ssh -o 'Protocol 2,1', or add to .ssh/config
|
||||
3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2)
|
||||
interop w/ ssh.com dsa-keys:
|
||||
|
@ -21,7 +21,7 @@ extern ServerOptions options;
|
||||
* return 1 on success, 0 on failure, -1 if krb4 is not available
|
||||
*/
|
||||
|
||||
int
|
||||
int
|
||||
auth_krb4_password(struct passwd * pw, const char *password)
|
||||
{
|
||||
AUTH_DAT adata;
|
||||
@ -137,7 +137,7 @@ krb4_cleanup_proc(void *ignore)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
krb4_init(uid_t uid)
|
||||
{
|
||||
static int cleanup_registered = 0;
|
||||
@ -181,7 +181,7 @@ krb4_init(uid_t uid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
auth_krb4(const char *server_user, KTEXT auth, char **client)
|
||||
{
|
||||
AUTH_DAT adat = {0};
|
||||
@ -254,7 +254,7 @@ auth_krb4(const char *server_user, KTEXT auth, char **client)
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifdef AFS
|
||||
int
|
||||
int
|
||||
auth_krb4_tgt(struct passwd *pw, const char *string)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
@ -309,7 +309,7 @@ auth_krb4_tgt(struct passwd *pw, const char *string)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
auth_afs_token(struct passwd *pw, const char *token_string)
|
||||
{
|
||||
CREDENTIALS creds;
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth-passwd.c,v 1.14 1999/12/29 12:47:46 markus Exp $");
|
||||
RCSID("$Id: auth-passwd.c,v 1.15 2000/04/14 10:30:29 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "ssh.h"
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* auth-rh-rsa.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Sun May 7 03:08:06 1995 ylo
|
||||
*
|
||||
*
|
||||
* Rhosts or /etc/hosts.equiv authentication combined with RSA host
|
||||
* authentication.
|
||||
*
|
||||
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth-rh-rsa.c,v 1.11 2000/03/23 22:15:33 markus Exp $");
|
||||
RCSID("$Id: auth-rh-rsa.c,v 1.13 2000/04/14 10:30:29 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "ssh.h"
|
||||
@ -34,7 +34,7 @@ RCSID("$Id: auth-rh-rsa.c,v 1.11 2000/03/23 22:15:33 markus Exp $");
|
||||
* its host key. Returns true if authentication succeeds.
|
||||
*/
|
||||
|
||||
int
|
||||
int
|
||||
auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key)
|
||||
{
|
||||
extern ServerOptions options;
|
||||
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* auth-rsa.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Mon Mar 27 01:46:52 1995 ylo
|
||||
*
|
||||
*
|
||||
* RSA-based authentication. This code determines whether to admit a login
|
||||
* based on RSA authentication. This file also contains functions to check
|
||||
* validity of the host key.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth-rsa.c,v 1.19 2000/03/23 22:15:33 markus Exp $");
|
||||
RCSID("$Id: auth-rsa.c,v 1.23 2000/04/29 18:11:51 markus Exp $");
|
||||
|
||||
#include "rsa.h"
|
||||
#include "packet.h"
|
||||
@ -186,6 +186,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
}
|
||||
}
|
||||
if (fail) {
|
||||
fclose(f);
|
||||
log(buf);
|
||||
packet_send_debug(buf);
|
||||
restore_uid();
|
||||
@ -239,7 +240,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
debug("%.100s, line %lu: bad key syntax",
|
||||
SSH_USER_PERMITTED_KEYS, linenum);
|
||||
packet_send_debug("%.100s, line %lu: bad key syntax",
|
||||
SSH_USER_PERMITTED_KEYS, linenum);
|
||||
SSH_USER_PERMITTED_KEYS, linenum);
|
||||
continue;
|
||||
}
|
||||
/* cp now points to the comment part. */
|
||||
@ -256,7 +257,6 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
|
||||
|
||||
/* We have found the desired key. */
|
||||
|
||||
|
||||
/* Perform the challenge-response dialog for this key. */
|
||||
if (!auth_rsa_challenge_dialog(pk)) {
|
||||
/* Wrong response. */
|
||||
|
@ -1,9 +1,12 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: auth-skey.c,v 1.6 2000/04/14 10:30:29 markus Exp $");
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
#include <sha1.h>
|
||||
#include <sha.h>
|
||||
|
||||
/*
|
||||
* try skey authentication,
|
||||
@ -14,7 +17,7 @@ int
|
||||
auth_skey_password(struct passwd * pw, const char *password)
|
||||
{
|
||||
if (strncasecmp(password, "s/key", 5) == 0) {
|
||||
char *skeyinfo = skey_keyinfo(pw->pw_name);
|
||||
char *skeyinfo = opie_keyinfo(pw->pw_name);
|
||||
if (skeyinfo == NULL) {
|
||||
debug("generating fake skeyinfo for %.100s.",
|
||||
pw->pw_name);
|
||||
@ -24,8 +27,8 @@ auth_skey_password(struct passwd * pw, const char *password)
|
||||
packet_send_debug(skeyinfo);
|
||||
/* Try again. */
|
||||
return 0;
|
||||
} else if (skey_haskey(pw->pw_name) == 0 &&
|
||||
skey_passcheck(pw->pw_name, (char *) password) != -1) {
|
||||
} else if (opie_haskey(pw->pw_name) == 0 &&
|
||||
opie_passverify(pw->pw_name, (char *) password) != -1) {
|
||||
/* Authentication succeeded. */
|
||||
return 1;
|
||||
}
|
||||
@ -64,16 +67,19 @@ skey_fake_keyinfo(char *username)
|
||||
{
|
||||
int i;
|
||||
u_int ptr;
|
||||
u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up;
|
||||
char pbuf[SKEY_MAX_PW_LEN+1];
|
||||
static char skeyprompt[SKEY_MAX_CHALLENGE+1];
|
||||
u_char hseed[OPIE_SEED_MAX], flg = 1, *up;
|
||||
char pbuf[OPIE_SECRET_MAX+1];
|
||||
static char skeyprompt[OPIE_CHALLENGE_MAX+1];
|
||||
char *secret = NULL;
|
||||
size_t secretlen = 0;
|
||||
SHA1_CTX ctx;
|
||||
char *p, *u;
|
||||
int mib[2];
|
||||
size_t size;
|
||||
struct timeval boottime;
|
||||
|
||||
/*
|
||||
* Base first 4 chars of seed on hostname.
|
||||
* Base first 2 chars of seed on hostname.
|
||||
* Add some filler for short hostnames if necessary.
|
||||
*/
|
||||
if (gethostname(pbuf, sizeof(pbuf)) == -1)
|
||||
@ -82,31 +88,34 @@ skey_fake_keyinfo(char *username)
|
||||
for (p = pbuf; *p && isalnum(*p); p++)
|
||||
if (isalpha(*p) && isupper(*p))
|
||||
*p = tolower(*p);
|
||||
if (*p && pbuf - p < 4)
|
||||
(void)strncpy(p, "asjd", 4 - (pbuf - p));
|
||||
pbuf[4] = '\0';
|
||||
if (*p && pbuf - p < 2)
|
||||
(void)strncpy(p, "asjd", 2 - (pbuf - p));
|
||||
pbuf[2] = '\0';
|
||||
|
||||
/* Hash the username if possible */
|
||||
if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) {
|
||||
if ((up = SHA1_Data(username, strlen(username), NULL)) != NULL) {
|
||||
struct stat sb;
|
||||
time_t t;
|
||||
int fd;
|
||||
|
||||
/* Collapse the hash */
|
||||
ptr = hash_collapse(up);
|
||||
memset(up, 0, strlen(up));
|
||||
|
||||
/* See if the random file's there, else use ctime */
|
||||
if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1
|
||||
&& fstat(fd, &sb) == 0 &&
|
||||
sb.st_size > (off_t)SKEY_MAX_SEED_LEN &&
|
||||
lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN),
|
||||
SEEK_SET) != -1 && read(fd, hseed,
|
||||
SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
secret = hseed;
|
||||
secretlen = SKEY_MAX_SEED_LEN;
|
||||
/*
|
||||
* Seed the fake challenge with the system boot time,
|
||||
* otherwise use ctime.
|
||||
*
|
||||
* XXX This should be a random source which is constant
|
||||
* over short time periods, but changes over timescales on
|
||||
* the order of a week.
|
||||
*/
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_BOOTTIME;
|
||||
size = sizeof(boottime);
|
||||
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
|
||||
boottime.tv_sec != 0) {
|
||||
secret = (char *)&boottime;
|
||||
secretlen = size/sizeof(char);
|
||||
flg = 0;
|
||||
} else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) {
|
||||
t = sb.st_ctime;
|
||||
@ -114,51 +123,49 @@ skey_fake_keyinfo(char *username)
|
||||
secretlen = strlen(secret);
|
||||
flg = 0;
|
||||
}
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* Put that in your pipe and smoke it */
|
||||
if (flg == 0) {
|
||||
/* Hash secret value with username */
|
||||
SHA1Init(&ctx);
|
||||
SHA1Update(&ctx, secret, secretlen);
|
||||
SHA1Update(&ctx, username, strlen(username));
|
||||
SHA1End(&ctx, up);
|
||||
SHA1_Init(&ctx);
|
||||
SHA1_Update(&ctx, secret, secretlen);
|
||||
SHA1_Update(&ctx, username, strlen(username));
|
||||
SHA1_End(&ctx, up);
|
||||
|
||||
/* Zero out */
|
||||
memset(secret, 0, secretlen);
|
||||
|
||||
/* Now hash the hash */
|
||||
SHA1Init(&ctx);
|
||||
SHA1Update(&ctx, up, strlen(up));
|
||||
SHA1End(&ctx, up);
|
||||
SHA1_Init(&ctx);
|
||||
SHA1_Update(&ctx, up, strlen(up));
|
||||
SHA1_End(&ctx, up);
|
||||
|
||||
ptr = hash_collapse(up + 4);
|
||||
|
||||
for (i = 4; i < 9; i++) {
|
||||
for (i = 2; i < 6; i++) {
|
||||
pbuf[i] = (ptr % 10) + '0';
|
||||
ptr /= 10;
|
||||
}
|
||||
pbuf[i] = '\0';
|
||||
|
||||
/* Sequence number */
|
||||
ptr = ((up[2] + up[3]) % 99) + 1;
|
||||
ptr = ((up[2] + up[3]) % 499) + 1;
|
||||
|
||||
memset(up, 0, 20); /* SHA1 specific */
|
||||
free(up);
|
||||
|
||||
(void)snprintf(skeyprompt, sizeof skeyprompt,
|
||||
"otp-%.*s %d %.*s",
|
||||
SKEY_MAX_HASHNAME_LEN,
|
||||
skey_get_algorithm(),
|
||||
ptr, SKEY_MAX_SEED_LEN,
|
||||
"opt-%.*s %d %.*s ext",
|
||||
OPIE_HASHNAME_MAX,
|
||||
opie_get_algorithm(),
|
||||
ptr, OPIE_SEED_MAX,
|
||||
pbuf);
|
||||
} else {
|
||||
/* Base last 8 chars of seed on username */
|
||||
/* Base last 4 chars of seed on username */
|
||||
u = username;
|
||||
i = 8;
|
||||
p = &pbuf[4];
|
||||
i = 4;
|
||||
p = &pbuf[2];
|
||||
do {
|
||||
if (*u == 0) {
|
||||
/* Pad remainder with zeros */
|
||||
@ -169,13 +176,11 @@ skey_fake_keyinfo(char *username)
|
||||
|
||||
*p++ = (*u++ % 10) + '0';
|
||||
} while (--i != 0);
|
||||
pbuf[12] = '\0';
|
||||
pbuf[6] = '\0';
|
||||
|
||||
(void)snprintf(skeyprompt, sizeof skeyprompt,
|
||||
"otp-%.*s %d %.*s",
|
||||
SKEY_MAX_HASHNAME_LEN,
|
||||
skey_get_algorithm(),
|
||||
99, SKEY_MAX_SEED_LEN, pbuf);
|
||||
"opt-md5 %d %.*s ext",
|
||||
499, OPIE_SEED_MAX, pbuf);
|
||||
}
|
||||
return skeyprompt;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@ -106,6 +108,16 @@ allowed_user(struct passwd * pw)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifndef __FreeBSD__ /* FreeBSD handle it later */
|
||||
/* Fail if the account's expiration time has passed. */
|
||||
if (pw->pw_expire != 0) {
|
||||
struct timeval tv;
|
||||
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
if (tv.tv_sec >= pw->pw_expire)
|
||||
return 0;
|
||||
}
|
||||
#endif /* !__FreeBSD__ */
|
||||
/* We found no reason not to let this user try to log on... */
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@ -39,9 +41,13 @@ get_authname(int type)
|
||||
case SSH_CMSG_AUTH_RHOSTS:
|
||||
return "rhosts";
|
||||
#ifdef KRB4
|
||||
case SSH_CMSG_AUTH_KERBEROS:
|
||||
return "kerberos";
|
||||
case SSH_CMSG_AUTH_KRB4:
|
||||
return "kerberosV4";
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
case SSH_CMSG_AUTH_KRB5:
|
||||
return "kerberosV5";
|
||||
#endif /* KRB5 */
|
||||
#ifdef SKEY
|
||||
case SSH_CMSG_AUTH_TIS_RESPONSE:
|
||||
return "s/key";
|
||||
@ -135,6 +141,31 @@ do_authloop(struct passwd * pw)
|
||||
unsigned int ulen;
|
||||
int type = 0;
|
||||
void (*authlog) (const char *fmt,...) = verbose;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif /* LOGIN_CAP */
|
||||
#if defined(LOGIN_CAP) || defined(LOGIN_ACCESS)
|
||||
const char *from_host, *from_ip;
|
||||
|
||||
from_host = get_canonical_hostname();
|
||||
from_ip = get_remote_ipaddr();
|
||||
#endif /* LOGIN_CAP || LOGIN_ACCESS */
|
||||
#ifdef HAVE_LIBPAM
|
||||
int pam_retval;
|
||||
#endif /* HAVE_LIBPAM */
|
||||
#if 0
|
||||
#ifdef KRB5
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_init_context(&ssh_context);
|
||||
if (ret)
|
||||
verbose("Error while initializing Kerberos V5.");
|
||||
krb5_init_ets(ssh_context);
|
||||
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
#endif
|
||||
|
||||
/* Indicate that authentication is needed. */
|
||||
packet_start(SSH_SMSG_FAILURE);
|
||||
@ -151,17 +182,17 @@ do_authloop(struct passwd * pw)
|
||||
/* Process the packet. */
|
||||
switch (type) {
|
||||
#ifdef AFS
|
||||
case SSH_CMSG_HAVE_KERBEROS_TGT:
|
||||
if (!options.kerberos_tgt_passing) {
|
||||
case SSH_CMSG_HAVE_KRB4_TGT:
|
||||
if (!options.krb4_tgt_passing) {
|
||||
/* packet_get_all(); */
|
||||
verbose("Kerberos tgt passing disabled.");
|
||||
verbose("Kerberos v4 tgt passing disabled.");
|
||||
break;
|
||||
} else {
|
||||
/* Accept Kerberos tgt. */
|
||||
/* Accept Kerberos v4 tgt. */
|
||||
char *tgt = packet_get_string(&dlen);
|
||||
packet_integrity_check(plen, 4 + dlen, type);
|
||||
if (!auth_kerberos_tgt(pw, tgt))
|
||||
verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
|
||||
if (!auth_krb4_tgt(pw, tgt))
|
||||
verbose("Kerberos v4 tgt REFUSED for %s", pw->pw_name);
|
||||
xfree(tgt);
|
||||
}
|
||||
continue;
|
||||
@ -182,11 +213,10 @@ do_authloop(struct passwd * pw)
|
||||
continue;
|
||||
#endif /* AFS */
|
||||
#ifdef KRB4
|
||||
case SSH_CMSG_AUTH_KERBEROS:
|
||||
if (!options.kerberos_authentication) {
|
||||
case SSH_CMSG_AUTH_KRB4:
|
||||
if (!options.krb4_authentication) {
|
||||
/* packet_get_all(); */
|
||||
verbose("Kerberos authentication disabled.");
|
||||
break;
|
||||
verbose("Kerberos v4 authentication disabled.");
|
||||
} else {
|
||||
/* Try Kerberos v4 authentication. */
|
||||
KTEXT_ST auth;
|
||||
@ -207,6 +237,36 @@ do_authloop(struct passwd * pw)
|
||||
}
|
||||
break;
|
||||
#endif /* KRB4 */
|
||||
#ifdef KRB5
|
||||
case SSH_CMSG_AUTH_KRB5:
|
||||
if (!options.krb5_authentication) {
|
||||
verbose("Kerberos v5 authentication disabled.");
|
||||
break;
|
||||
} else {
|
||||
krb5_data k5data;
|
||||
#if 0
|
||||
if (krb5_init_context(&ssh_context)) {
|
||||
verbose("Error while initializing Kerberos V5.");
|
||||
break;
|
||||
}
|
||||
krb5_init_ets(ssh_context);
|
||||
#endif
|
||||
|
||||
k5data.data = packet_get_string(&k5data.length);
|
||||
packet_integrity_check(plen, 4 + k5data.length, type);
|
||||
if (auth_krb5(pw->pw_name, &k5data, &tkt_client)) {
|
||||
/* pw->name is passed just for logging purposes
|
||||
* */
|
||||
/* authorize client against .k5login */
|
||||
if (krb5_kuserok(ssh_context,
|
||||
tkt_client,
|
||||
pw->pw_name))
|
||||
authenticated = 1;
|
||||
}
|
||||
xfree(k5data.data);
|
||||
}
|
||||
break;
|
||||
#endif /* KRB5 */
|
||||
|
||||
case SSH_CMSG_AUTH_RHOSTS:
|
||||
if (!options.rhosts_authentication) {
|
||||
@ -303,7 +363,7 @@ do_authloop(struct passwd * pw)
|
||||
case SSH_CMSG_AUTH_TIS:
|
||||
debug("rcvd SSH_CMSG_AUTH_TIS");
|
||||
if (options.skey_authentication == 1) {
|
||||
char *skeyinfo = skey_keyinfo(pw->pw_name);
|
||||
char *skeyinfo = opie_keyinfo(pw->pw_name);
|
||||
if (skeyinfo == NULL) {
|
||||
debug("generating fake skeyinfo for %.100s.", pw->pw_name);
|
||||
skeyinfo = skey_fake_keyinfo(pw->pw_name);
|
||||
@ -325,8 +385,8 @@ do_authloop(struct passwd * pw)
|
||||
char *response = packet_get_string(&dlen);
|
||||
debug("skey response == '%s'", response);
|
||||
packet_integrity_check(plen, 4 + dlen, type);
|
||||
authenticated = (skey_haskey(pw->pw_name) == 0 &&
|
||||
skey_passcheck(pw->pw_name, response) != -1);
|
||||
authenticated = (opie_haskey(pw->pw_name) == 0 &&
|
||||
opie_passverify(pw->pw_name, response) != -1);
|
||||
xfree(response);
|
||||
}
|
||||
break;
|
||||
@ -336,6 +396,32 @@ do_authloop(struct passwd * pw)
|
||||
log("TIS authentication unsupported.");
|
||||
break;
|
||||
#endif
|
||||
#ifdef KRB5
|
||||
case SSH_CMSG_HAVE_KRB5_TGT:
|
||||
/* Passing krb5 ticket */
|
||||
if (!options.krb5_tgt_passing
|
||||
/*|| !options.krb5_authentication */) {
|
||||
|
||||
}
|
||||
|
||||
if (tkt_client == NULL) {
|
||||
/* passing tgt without krb5 authentication */
|
||||
}
|
||||
|
||||
{
|
||||
krb5_data tgt;
|
||||
tgt.data = packet_get_string(&tgt.length);
|
||||
|
||||
if (!auth_krb5_tgt(pw->pw_name, &tgt, tkt_client)) {
|
||||
verbose ("Kerberos V5 TGT refused for %.100s", pw->pw_name);
|
||||
xfree(tgt.data);
|
||||
goto fail;
|
||||
}
|
||||
xfree(tgt.data);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
|
||||
default:
|
||||
/*
|
||||
@ -359,6 +445,34 @@ do_authloop(struct passwd * pw)
|
||||
log("ROOT LOGIN REFUSED FROM %.200s",
|
||||
get_canonical_hostname());
|
||||
}
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
lc = login_getpwclass(pw);
|
||||
if (lc == NULL)
|
||||
lc = login_getclassbyname(NULL, pw);
|
||||
if (!auth_hostok(lc, from_host, from_ip)) {
|
||||
log("Denied connection for %.200s from %.200s [%.200s].",
|
||||
pw->pw_name, from_host, from_ip);
|
||||
packet_disconnect("Sorry, you are not allowed to connect.");
|
||||
}
|
||||
if (!auth_timeok(lc, time(NULL))) {
|
||||
log("LOGIN %.200s REFUSED (TIME) FROM %.200s",
|
||||
pw->pw_name, from_host);
|
||||
packet_disconnect("Logins not available right now.");
|
||||
}
|
||||
login_close(lc);
|
||||
#endif /* LOGIN_CAP */
|
||||
#ifdef LOGIN_ACCESS
|
||||
if (!login_access(pw->pw_name, from_host)) {
|
||||
log("Denied connection for %.200s from %.200s [%.200s].",
|
||||
pw->pw_name, from_host, from_ip);
|
||||
packet_disconnect("Sorry, you are not allowed to connect.");
|
||||
}
|
||||
#endif /* LOGIN_ACCESS */
|
||||
|
||||
if (pw->pw_uid == 0)
|
||||
log("ROOT LOGIN as '%.100s' from %.100s",
|
||||
pw->pw_name, get_canonical_hostname());
|
||||
}
|
||||
|
||||
/* Raise logging level */
|
||||
@ -431,6 +545,9 @@ do_authentication()
|
||||
pwcopy.pw_gid = pw->pw_gid;
|
||||
pwcopy.pw_dir = xstrdup(pw->pw_dir);
|
||||
pwcopy.pw_shell = xstrdup(pw->pw_shell);
|
||||
pwcopy.pw_class = xstrdup(pw->pw_class);
|
||||
pwcopy.pw_expire = pw->pw_expire;
|
||||
pwcopy.pw_change = pw->pw_change;
|
||||
pw = &pwcopy;
|
||||
|
||||
/*
|
||||
@ -444,8 +561,11 @@ do_authentication()
|
||||
|
||||
/* If the user has no password, accept authentication immediately. */
|
||||
if (options.password_authentication &&
|
||||
#ifdef KRB5
|
||||
!options.krb5_authentication &&
|
||||
#endif /* KRB5 */
|
||||
#ifdef KRB4
|
||||
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
|
||||
(!options.krb4_authentication || options.krb4_or_local_passwd) &&
|
||||
#endif /* KRB4 */
|
||||
auth_password(pw, "")) {
|
||||
/* Authentication with empty password succeeded. */
|
||||
|
@ -25,6 +25,8 @@
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2.c,v 1.8 2000/05/08 17:42:24 markus Exp $");
|
||||
@ -97,7 +99,7 @@ do_authentication2()
|
||||
options.skey_authentication = 0;
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
options.kerberos_authentication = 0;
|
||||
options.krb4_authentication = 0;
|
||||
#endif
|
||||
|
||||
dispatch_init(&protocol_error);
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* authfd.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Wed Mar 29 01:30:28 1995 ylo
|
||||
*
|
||||
*
|
||||
* Functions for connecting the local authentication agent.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: authfd.c,v 1.16 1999/12/15 19:43:10 markus Exp $");
|
||||
RCSID("$Id: authfd.c,v 1.19 2000/04/29 18:11:52 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "rsa.h"
|
||||
@ -65,7 +65,7 @@ ssh_get_authentication_socket()
|
||||
* ssh_get_authentication_socket().
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
ssh_close_authentication_socket(int sock)
|
||||
{
|
||||
if (getenv(SSH_AUTHSOCKET_ENV_NAME))
|
||||
@ -109,7 +109,7 @@ ssh_get_authentication_connection()
|
||||
* memory.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
ssh_close_authentication_connection(AuthenticationConnection *ac)
|
||||
{
|
||||
buffer_free(&ac->packet);
|
||||
@ -218,8 +218,8 @@ ssh_get_next_identity(AuthenticationConnection *auth,
|
||||
*comment = buffer_get_string(&auth->identities, NULL);
|
||||
|
||||
if (bits != BN_num_bits(n))
|
||||
error("Warning: identity keysize mismatch: actual %d, announced %u",
|
||||
BN_num_bits(n), bits);
|
||||
log("Warning: identity keysize mismatch: actual %d, announced %u",
|
||||
BN_num_bits(n), bits);
|
||||
|
||||
/* Decrement the number of remaining entries. */
|
||||
auth->howmany--;
|
||||
@ -339,7 +339,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
|
||||
* be used by normal applications.
|
||||
*/
|
||||
|
||||
int
|
||||
int
|
||||
ssh_add_identity(AuthenticationConnection *auth,
|
||||
RSA * key, const char *comment)
|
||||
{
|
||||
@ -427,7 +427,7 @@ ssh_add_identity(AuthenticationConnection *auth,
|
||||
* meant to be used by normal applications.
|
||||
*/
|
||||
|
||||
int
|
||||
int
|
||||
ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
|
||||
{
|
||||
Buffer buffer;
|
||||
@ -510,7 +510,7 @@ ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
|
||||
* by normal applications.
|
||||
*/
|
||||
|
||||
int
|
||||
int
|
||||
ssh_remove_all_identities(AuthenticationConnection *auth)
|
||||
{
|
||||
Buffer buffer;
|
||||
|
@ -1,29 +1,35 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* authfile.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Mon Mar 27 03:52:05 1995 ylo
|
||||
*
|
||||
*
|
||||
* This file contains functions for reading and writing identity files, and
|
||||
* for reading the passphrase from the user.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: authfile.c,v 1.11 1999/12/06 19:11:15 deraadt Exp $");
|
||||
RCSID("$Id: authfile.c,v 1.16 2000/04/26 21:28:32 markus Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "cipher.h"
|
||||
#include "ssh.h"
|
||||
#include "key.h"
|
||||
|
||||
/* Version identification string for identity files. */
|
||||
#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n"
|
||||
@ -36,8 +42,8 @@ RCSID("$Id: authfile.c,v 1.11 1999/12/06 19:11:15 deraadt Exp $");
|
||||
*/
|
||||
|
||||
int
|
||||
save_private_key(const char *filename, const char *passphrase,
|
||||
RSA *key, const char *comment)
|
||||
save_private_key_rsa(const char *filename, const char *passphrase,
|
||||
RSA *key, const char *comment)
|
||||
{
|
||||
Buffer buffer, encrypted;
|
||||
char buf[100], *cp;
|
||||
@ -102,7 +108,7 @@ save_private_key(const char *filename, const char *passphrase,
|
||||
/* Allocate space for the private part of the key in the buffer. */
|
||||
buffer_append_space(&encrypted, &cp, buffer_len(&buffer));
|
||||
|
||||
cipher_set_key_string(&cipher, cipher_type, passphrase, 1);
|
||||
cipher_set_key_string(&cipher, cipher_type, passphrase);
|
||||
cipher_encrypt(&cipher, (unsigned char *) cp,
|
||||
(unsigned char *) buffer_ptr(&buffer),
|
||||
buffer_len(&buffer));
|
||||
@ -129,6 +135,63 @@ save_private_key(const char *filename, const char *passphrase,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* save DSA key in OpenSSL PEM format */
|
||||
|
||||
int
|
||||
save_private_key_dsa(const char *filename, const char *passphrase,
|
||||
DSA *dsa, const char *comment)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
int success = 1;
|
||||
int len = strlen(passphrase);
|
||||
|
||||
if (len > 0 && len <= 4) {
|
||||
error("passphrase too short: %d bytes", len);
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0) {
|
||||
debug("open %s failed", filename);
|
||||
return 0;
|
||||
}
|
||||
fp = fdopen(fd, "w");
|
||||
if (fp == NULL ) {
|
||||
debug("fdopen %s failed", filename);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (len > 0) {
|
||||
if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(),
|
||||
(char *)passphrase, strlen(passphrase), NULL, NULL))
|
||||
success = 0;
|
||||
} else {
|
||||
if (!PEM_write_DSAPrivateKey(fp, dsa, NULL,
|
||||
NULL, 0, NULL, NULL))
|
||||
success = 0;
|
||||
}
|
||||
fclose(fp);
|
||||
return success;
|
||||
}
|
||||
|
||||
int
|
||||
save_private_key(const char *filename, const char *passphrase, Key *key,
|
||||
const char *comment)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
return save_private_key_rsa(filename, passphrase, key->rsa, comment);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
return save_private_key_dsa(filename, passphrase, key->dsa, comment);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the public part of the key file. Returns 0 if an error was
|
||||
* encountered (the file does not exist or is not readable), and non-zero
|
||||
@ -136,8 +199,7 @@ save_private_key(const char *filename, const char *passphrase,
|
||||
*/
|
||||
|
||||
int
|
||||
load_public_key(const char *filename, RSA * pub,
|
||||
char **comment_return)
|
||||
load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
|
||||
{
|
||||
int fd, i;
|
||||
off_t len;
|
||||
@ -155,7 +217,7 @@ load_public_key(const char *filename, RSA * pub,
|
||||
|
||||
if (read(fd, cp, (size_t) len) != (size_t) len) {
|
||||
debug("Read from key file %.200s failed: %.100s", filename,
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
buffer_free(&buffer);
|
||||
close(fd);
|
||||
return 0;
|
||||
@ -184,9 +246,13 @@ load_public_key(const char *filename, RSA * pub,
|
||||
|
||||
/* Read the public key from the buffer. */
|
||||
buffer_get_int(&buffer);
|
||||
pub->n = BN_new();
|
||||
/* XXX alloc */
|
||||
if (pub->n == NULL)
|
||||
pub->n = BN_new();
|
||||
buffer_get_bignum(&buffer, pub->n);
|
||||
pub->e = BN_new();
|
||||
/* XXX alloc */
|
||||
if (pub->e == NULL)
|
||||
pub->e = BN_new();
|
||||
buffer_get_bignum(&buffer, pub->e);
|
||||
if (comment_return)
|
||||
*comment_return = buffer_get_string(&buffer, NULL);
|
||||
@ -197,6 +263,20 @@ load_public_key(const char *filename, RSA * pub,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
load_public_key(const char *filename, Key * key, char **comment_return)
|
||||
{
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
return load_public_key_rsa(filename, key->rsa, comment_return);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the private key from the file. Returns 0 if an error is encountered
|
||||
* (file does not exist or is not readable, or passphrase is bad). This
|
||||
@ -205,35 +285,17 @@ load_public_key(const char *filename, RSA * pub,
|
||||
*/
|
||||
|
||||
int
|
||||
load_private_key(const char *filename, const char *passphrase,
|
||||
RSA * prv, char **comment_return)
|
||||
load_private_key_rsa(int fd, const char *filename,
|
||||
const char *passphrase, RSA * prv, char **comment_return)
|
||||
{
|
||||
int fd, i, check1, check2, cipher_type;
|
||||
int i, check1, check2, cipher_type;
|
||||
off_t len;
|
||||
Buffer buffer, decrypted;
|
||||
char *cp;
|
||||
CipherContext cipher;
|
||||
BN_CTX *ctx;
|
||||
BIGNUM *aux;
|
||||
struct stat st;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
/* check owner and modes */
|
||||
if (fstat(fd, &st) < 0 ||
|
||||
(st.st_uid != 0 && st.st_uid != getuid()) ||
|
||||
(st.st_mode & 077) != 0) {
|
||||
close(fd);
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("Bad ownership or mode(0%3.3o) for '%s'.",
|
||||
st.st_mode & 0777, filename);
|
||||
error("It is recommended that your private key files are NOT accessible by others.");
|
||||
return 0;
|
||||
}
|
||||
len = lseek(fd, (off_t) 0, SEEK_END);
|
||||
lseek(fd, (off_t) 0, SEEK_SET);
|
||||
|
||||
@ -281,7 +343,7 @@ load_private_key(const char *filename, const char *passphrase,
|
||||
xfree(buffer_get_string(&buffer, NULL));
|
||||
|
||||
/* Check that it is a supported cipher. */
|
||||
if (((cipher_mask() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
|
||||
if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
|
||||
(1 << cipher_type)) == 0) {
|
||||
debug("Unsupported cipher %.100s used in key file %.200s.",
|
||||
cipher_name(cipher_type), filename);
|
||||
@ -293,7 +355,7 @@ load_private_key(const char *filename, const char *passphrase,
|
||||
buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
|
||||
|
||||
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
|
||||
cipher_set_key_string(&cipher, cipher_type, passphrase, 0);
|
||||
cipher_set_key_string(&cipher, cipher_type, passphrase);
|
||||
cipher_decrypt(&cipher, (unsigned char *) cp,
|
||||
(unsigned char *) buffer_ptr(&buffer),
|
||||
buffer_len(&buffer));
|
||||
@ -310,7 +372,9 @@ load_private_key(const char *filename, const char *passphrase,
|
||||
buffer_free(&decrypted);
|
||||
fail:
|
||||
BN_clear_free(prv->n);
|
||||
prv->n = NULL;
|
||||
BN_clear_free(prv->e);
|
||||
prv->e = NULL;
|
||||
if (comment_return)
|
||||
xfree(*comment_return);
|
||||
return 0;
|
||||
@ -344,3 +408,87 @@ load_private_key(const char *filename, const char *passphrase,
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return)
|
||||
{
|
||||
DSA *dsa;
|
||||
BIO *in;
|
||||
FILE *fp;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL) {
|
||||
error("BIO_new failed");
|
||||
return 0;
|
||||
}
|
||||
fp = fdopen(fd, "r");
|
||||
if (fp == NULL) {
|
||||
error("fdopen failed");
|
||||
return 0;
|
||||
}
|
||||
BIO_set_fp(in, fp, BIO_NOCLOSE);
|
||||
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase);
|
||||
if (dsa == NULL) {
|
||||
debug("PEM_read_bio_DSAPrivateKey failed");
|
||||
} else {
|
||||
/* replace k->dsa with loaded key */
|
||||
DSA_free(k->dsa);
|
||||
k->dsa = dsa;
|
||||
}
|
||||
BIO_free(in);
|
||||
fclose(fp);
|
||||
if (comment_return)
|
||||
*comment_return = xstrdup("dsa w/o comment");
|
||||
debug("read DSA private key done");
|
||||
#ifdef DEBUG_DSS
|
||||
DSA_print_fp(stderr, dsa, 8);
|
||||
#endif
|
||||
return dsa != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
load_private_key(const char *filename, const char *passphrase, Key *key,
|
||||
char **comment_return)
|
||||
{
|
||||
int fd;
|
||||
int ret = 0;
|
||||
struct stat st;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
/* check owner and modes */
|
||||
if (fstat(fd, &st) < 0 ||
|
||||
(st.st_uid != 0 && st.st_uid != getuid()) ||
|
||||
(st.st_mode & 077) != 0) {
|
||||
close(fd);
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
|
||||
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
||||
error("Bad ownership or mode(0%3.3o) for '%s'.",
|
||||
st.st_mode & 0777, filename);
|
||||
error("It is recommended that your private key files are NOT accessible by others.");
|
||||
return 0;
|
||||
}
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
if (key->rsa->e != NULL) {
|
||||
BN_clear_free(key->rsa->e);
|
||||
key->rsa->e = NULL;
|
||||
}
|
||||
if (key->rsa->n != NULL) {
|
||||
BN_clear_free(key->rsa->n);
|
||||
key->rsa->n = NULL;
|
||||
}
|
||||
ret = load_private_key_rsa(fd, filename, passphrase,
|
||||
key->rsa, comment_return);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
ret = load_private_key_dsa(fd, passphrase, key, comment_return);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,22 +1,24 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* bufaux.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Wed Mar 29 02:24:47 1995 ylo
|
||||
*
|
||||
*
|
||||
* Auxiliary functions for storing and retrieving various data types to/from
|
||||
* Buffers.
|
||||
*
|
||||
* SSH2 packet format added by Markus Friedl
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: bufaux.c,v 1.8 2000/03/16 20:56:14 markus Exp $");
|
||||
RCSID("$Id: bufaux.c,v 1.11 2000/04/14 10:30:30 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include <openssl/bn.h>
|
||||
@ -76,10 +78,54 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value)
|
||||
return 2 + bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores an BIGNUM in the buffer in SSH2 format.
|
||||
*/
|
||||
void
|
||||
buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
int bytes = BN_num_bytes(value) + 1;
|
||||
unsigned char *buf = xmalloc(bytes);
|
||||
int oi;
|
||||
int hasnohigh = 0;
|
||||
buf[0] = '\0';
|
||||
/* Get the value of in binary */
|
||||
oi = BN_bn2bin(value, buf+1);
|
||||
if (oi != bytes-1)
|
||||
fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
|
||||
oi, bytes);
|
||||
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
|
||||
if (value->neg) {
|
||||
/**XXX should be two's-complement */
|
||||
int i, carry;
|
||||
unsigned char *uc = buf;
|
||||
log("negativ!");
|
||||
for(i = bytes-1, carry = 1; i>=0; i--) {
|
||||
uc[i] ^= 0xff;
|
||||
if(carry)
|
||||
carry = !++uc[i];
|
||||
}
|
||||
}
|
||||
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
|
||||
memset(buf, 0, bytes);
|
||||
xfree(buf);
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
/**XXX should be two's-complement */
|
||||
int len;
|
||||
unsigned char *bin = (unsigned char *)buffer_get_string(buffer, (unsigned int *)&len);
|
||||
BN_bin2bn(bin, len, value);
|
||||
xfree(bin);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an integer from the buffer (4 bytes, msb first).
|
||||
*/
|
||||
unsigned int
|
||||
unsigned int
|
||||
buffer_get_int(Buffer *buffer)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
@ -90,7 +136,7 @@ buffer_get_int(Buffer *buffer)
|
||||
/*
|
||||
* Stores an integer in the buffer in 4 bytes, msb first.
|
||||
*/
|
||||
void
|
||||
void
|
||||
buffer_put_int(Buffer *buffer, unsigned int value)
|
||||
{
|
||||
char buf[4];
|
||||
@ -130,17 +176,22 @@ buffer_get_string(Buffer *buffer, unsigned int *length_ptr)
|
||||
/*
|
||||
* Stores and arbitrary binary string in the buffer.
|
||||
*/
|
||||
void
|
||||
void
|
||||
buffer_put_string(Buffer *buffer, const void *buf, unsigned int len)
|
||||
{
|
||||
buffer_put_int(buffer, len);
|
||||
buffer_append(buffer, buf, len);
|
||||
}
|
||||
void
|
||||
buffer_put_cstring(Buffer *buffer, const char *s)
|
||||
{
|
||||
buffer_put_string(buffer, s, strlen(s));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a character from the buffer (0 - 255).
|
||||
*/
|
||||
int
|
||||
int
|
||||
buffer_get_char(Buffer *buffer)
|
||||
{
|
||||
char ch;
|
||||
@ -151,7 +202,7 @@ buffer_get_char(Buffer *buffer)
|
||||
/*
|
||||
* Stores a character in the buffer.
|
||||
*/
|
||||
void
|
||||
void
|
||||
buffer_put_char(Buffer *buffer, int value)
|
||||
{
|
||||
char ch = value;
|
||||
|
@ -1,27 +1,30 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* cipher.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Wed Apr 19 17:41:39 1995 ylo
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: cipher.c,v 1.20 2000/03/22 09:55:10 markus Exp $");
|
||||
RCSID("$Id: cipher.c,v 1.26 2000/04/14 10:30:30 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "cipher.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
/*
|
||||
* What kind of tripple DES are these 2 routines?
|
||||
* This is used by SSH1:
|
||||
*
|
||||
* What kind of triple DES are these 2 routines?
|
||||
*
|
||||
* Why is there a redundant initialization vector?
|
||||
*
|
||||
@ -76,7 +79,7 @@ SSH_3CBC_DECRYPT(des_key_schedule ks1,
|
||||
}
|
||||
|
||||
/*
|
||||
* SSH uses a variation on Blowfish, all bytes must be swapped before
|
||||
* SSH1 uses a variation on Blowfish, all bytes must be swapped before
|
||||
* and after encryption/decryption. Thus the swap_bytes stuff (yuk).
|
||||
*/
|
||||
static void
|
||||
@ -117,7 +120,12 @@ static char *cipher_names[] =
|
||||
"3des",
|
||||
"tss",
|
||||
"rc4",
|
||||
"blowfish"
|
||||
"blowfish",
|
||||
"reserved",
|
||||
"blowfish-cbc",
|
||||
"3des-cbc",
|
||||
"arcfour",
|
||||
"cast128-cbc"
|
||||
};
|
||||
|
||||
/*
|
||||
@ -126,14 +134,29 @@ static char *cipher_names[] =
|
||||
* supported cipher.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
cipher_mask()
|
||||
unsigned int
|
||||
cipher_mask1()
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
|
||||
mask |= 1 << SSH_CIPHER_BLOWFISH;
|
||||
return mask;
|
||||
}
|
||||
unsigned int
|
||||
cipher_mask2()
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
mask |= 1 << SSH_CIPHER_BLOWFISH_CBC;
|
||||
mask |= 1 << SSH_CIPHER_3DES_CBC;
|
||||
mask |= 1 << SSH_CIPHER_ARCFOUR;
|
||||
mask |= 1 << SSH_CIPHER_CAST128_CBC;
|
||||
return mask;
|
||||
}
|
||||
unsigned int
|
||||
cipher_mask()
|
||||
{
|
||||
return cipher_mask1() | cipher_mask2();
|
||||
}
|
||||
|
||||
/* Returns the name of the cipher. */
|
||||
|
||||
@ -142,10 +165,34 @@ cipher_name(int cipher)
|
||||
{
|
||||
if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) ||
|
||||
cipher_names[cipher] == NULL)
|
||||
fatal("cipher_name: bad cipher number: %d", cipher);
|
||||
fatal("cipher_name: bad cipher name: %d", cipher);
|
||||
return cipher_names[cipher];
|
||||
}
|
||||
|
||||
/* Returns 1 if the name of the ciphers are valid. */
|
||||
|
||||
#define CIPHER_SEP ","
|
||||
int
|
||||
ciphers_valid(const char *names)
|
||||
{
|
||||
char *ciphers;
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
if (strcmp(names, "") == 0)
|
||||
return 0;
|
||||
ciphers = xstrdup(names);
|
||||
for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) {
|
||||
i = cipher_number(p);
|
||||
if (i == -1 || !(cipher_mask2() & (1 << i))) {
|
||||
xfree(ciphers);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
xfree(ciphers);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses the name of the cipher. Returns the number of the corresponding
|
||||
* cipher, or -1 on error.
|
||||
@ -167,9 +214,8 @@ cipher_number(const char *name)
|
||||
* passphrase and using the resulting 16 bytes as the key.
|
||||
*/
|
||||
|
||||
void
|
||||
cipher_set_key_string(CipherContext *context, int cipher,
|
||||
const char *passphrase, int for_encryption)
|
||||
void
|
||||
cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase)
|
||||
{
|
||||
MD5_CTX md;
|
||||
unsigned char digest[16];
|
||||
@ -178,7 +224,7 @@ cipher_set_key_string(CipherContext *context, int cipher,
|
||||
MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase));
|
||||
MD5_Final(digest, &md);
|
||||
|
||||
cipher_set_key(context, cipher, digest, 16, for_encryption);
|
||||
cipher_set_key(context, cipher, digest, 16);
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(&md, 0, sizeof(md));
|
||||
@ -186,9 +232,9 @@ cipher_set_key_string(CipherContext *context, int cipher,
|
||||
|
||||
/* Selects the cipher to use and sets the key. */
|
||||
|
||||
void
|
||||
cipher_set_key(CipherContext *context, int cipher,
|
||||
const unsigned char *key, int keylen, int for_encryption)
|
||||
void
|
||||
cipher_set_key(CipherContext *context, int cipher, const unsigned char *key,
|
||||
int keylen)
|
||||
{
|
||||
unsigned char padded[32];
|
||||
|
||||
@ -228,19 +274,86 @@ cipher_set_key(CipherContext *context, int cipher,
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_BLOWFISH:
|
||||
if (keylen < 16)
|
||||
error("Key length %d is insufficient for blowfish.", keylen);
|
||||
BF_set_key(&context->u.bf.key, keylen, padded);
|
||||
memset(context->u.bf.iv, 0, 8);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_3DES_CBC:
|
||||
case SSH_CIPHER_BLOWFISH_CBC:
|
||||
case SSH_CIPHER_ARCFOUR:
|
||||
case SSH_CIPHER_CAST128_CBC:
|
||||
fatal("cipher_set_key: illegal cipher: %s", cipher_name(cipher));
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
|
||||
}
|
||||
memset(padded, 0, sizeof(padded));
|
||||
}
|
||||
|
||||
void
|
||||
cipher_set_key_iv(CipherContext * context, int cipher,
|
||||
const unsigned char *key, int keylen,
|
||||
const unsigned char *iv, int ivlen)
|
||||
{
|
||||
/* Set cipher type. */
|
||||
context->type = cipher;
|
||||
|
||||
/* Initialize the initialization vector. */
|
||||
switch (cipher) {
|
||||
case SSH_CIPHER_NONE:
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_3DES:
|
||||
case SSH_CIPHER_BLOWFISH:
|
||||
fatal("cipher_set_key_iv: illegal cipher: %s", cipher_name(cipher));
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_3DES_CBC:
|
||||
if (keylen < 24)
|
||||
error("Key length %d is insufficient for 3des-cbc.", keylen);
|
||||
des_set_key((void *) key, context->u.des3.key1);
|
||||
des_set_key((void *) (key+8), context->u.des3.key2);
|
||||
des_set_key((void *) (key+16), context->u.des3.key3);
|
||||
if (ivlen < 8)
|
||||
error("IV length %d is insufficient for 3des-cbc.", ivlen);
|
||||
memcpy(context->u.des3.iv3, (char *)iv, 8);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_BLOWFISH_CBC:
|
||||
if (keylen < 16)
|
||||
error("Key length %d is insufficient for blowfish.", keylen);
|
||||
if (ivlen < 8)
|
||||
error("IV length %d is insufficient for blowfish.", ivlen);
|
||||
BF_set_key(&context->u.bf.key, keylen, (unsigned char *)key);
|
||||
memcpy(context->u.bf.iv, (char *)iv, 8);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_ARCFOUR:
|
||||
if (keylen < 16)
|
||||
error("Key length %d is insufficient for arcfour.", keylen);
|
||||
RC4_set_key(&context->u.rc4, keylen, (unsigned char *)key);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_CAST128_CBC:
|
||||
if (keylen < 16)
|
||||
error("Key length %d is insufficient for cast128.", keylen);
|
||||
if (ivlen < 8)
|
||||
error("IV length %d is insufficient for cast128.", ivlen);
|
||||
CAST_set_key(&context->u.cast.key, keylen, (unsigned char *) key);
|
||||
memcpy(context->u.cast.iv, (char *)iv, 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("cipher_set_key: unknown cipher: %s", cipher_name(cipher));
|
||||
}
|
||||
}
|
||||
|
||||
/* Encrypts data using the cipher. */
|
||||
|
||||
void
|
||||
void
|
||||
cipher_encrypt(CipherContext *context, unsigned char *dest,
|
||||
const unsigned char *src, unsigned int len)
|
||||
{
|
||||
@ -262,11 +375,32 @@ cipher_encrypt(CipherContext *context, unsigned char *dest,
|
||||
case SSH_CIPHER_BLOWFISH:
|
||||
swap_bytes(src, dest, len);
|
||||
BF_cbc_encrypt(dest, dest, len,
|
||||
&context->u.bf.key, context->u.bf.iv,
|
||||
&context->u.bf.key, context->u.bf.iv,
|
||||
BF_ENCRYPT);
|
||||
swap_bytes(dest, dest, len);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_BLOWFISH_CBC:
|
||||
BF_cbc_encrypt((void *)src, dest, len,
|
||||
&context->u.bf.key, context->u.bf.iv,
|
||||
BF_ENCRYPT);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_3DES_CBC:
|
||||
des_ede3_cbc_encrypt(src, dest, len,
|
||||
context->u.des3.key1, context->u.des3.key2,
|
||||
context->u.des3.key3, &context->u.des3.iv3, DES_ENCRYPT);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_ARCFOUR:
|
||||
RC4(&context->u.rc4, len, (unsigned char *)src, dest);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_CAST128_CBC:
|
||||
CAST_cbc_encrypt(src, dest, len,
|
||||
&context->u.cast.key, context->u.cast.iv, CAST_ENCRYPT);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("cipher_encrypt: unknown cipher: %s", cipher_name(context->type));
|
||||
}
|
||||
@ -274,7 +408,7 @@ cipher_encrypt(CipherContext *context, unsigned char *dest,
|
||||
|
||||
/* Decrypts data using the cipher. */
|
||||
|
||||
void
|
||||
void
|
||||
cipher_decrypt(CipherContext *context, unsigned char *dest,
|
||||
const unsigned char *src, unsigned int len)
|
||||
{
|
||||
@ -301,6 +435,27 @@ cipher_decrypt(CipherContext *context, unsigned char *dest,
|
||||
swap_bytes(dest, dest, len);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_BLOWFISH_CBC:
|
||||
BF_cbc_encrypt((void *) src, dest, len,
|
||||
&context->u.bf.key, context->u.bf.iv,
|
||||
BF_DECRYPT);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_3DES_CBC:
|
||||
des_ede3_cbc_encrypt(src, dest, len,
|
||||
context->u.des3.key1, context->u.des3.key2,
|
||||
context->u.des3.key3, &context->u.des3.iv3, DES_DECRYPT);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_ARCFOUR:
|
||||
RC4(&context->u.rc4, len, (unsigned char *)src, dest);
|
||||
break;
|
||||
|
||||
case SSH_CIPHER_CAST128_CBC:
|
||||
CAST_cbc_encrypt(src, dest, len,
|
||||
&context->u.cast.key, context->u.cast.iv, CAST_DECRYPT);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("cipher_decrypt: unknown cipher: %s", cipher_name(context->type));
|
||||
}
|
||||
|
@ -1,27 +1,30 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* cipher.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Wed Apr 19 16:50:42 1995 ylo
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: cipher.h,v 1.11 2000/03/22 09:55:10 markus Exp $"); */
|
||||
/* RCSID("$Id: cipher.h,v 1.17 2000/05/08 17:12:15 markus Exp $"); */
|
||||
|
||||
#ifndef CIPHER_H
|
||||
#define CIPHER_H
|
||||
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/cast.h>
|
||||
|
||||
/* Cipher types. New types can be added, but old types should not be removed
|
||||
for compatibility. The maximum allowed value is 31. */
|
||||
#define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */
|
||||
#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */
|
||||
#define SSH_CIPHER_NONE 0 /* no encryption */
|
||||
#define SSH_CIPHER_IDEA 1 /* IDEA CFB */
|
||||
@ -30,6 +33,13 @@
|
||||
#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */
|
||||
#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */
|
||||
#define SSH_CIPHER_BLOWFISH 6
|
||||
#define SSH_CIPHER_RESERVED 7
|
||||
|
||||
/* these ciphers are used in SSH2: */
|
||||
#define SSH_CIPHER_BLOWFISH_CBC 8
|
||||
#define SSH_CIPHER_3DES_CBC 9
|
||||
#define SSH_CIPHER_ARCFOUR 10 /* Alleged RC4 */
|
||||
#define SSH_CIPHER_CAST128_CBC 11
|
||||
|
||||
typedef struct {
|
||||
unsigned int type;
|
||||
@ -45,6 +55,11 @@ typedef struct {
|
||||
struct bf_key_st key;
|
||||
unsigned char iv[8];
|
||||
} bf;
|
||||
struct {
|
||||
CAST_KEY key;
|
||||
unsigned char iv[8];
|
||||
} cast;
|
||||
RC4_KEY rc4;
|
||||
} u;
|
||||
} CipherContext;
|
||||
/*
|
||||
@ -53,6 +68,8 @@ typedef struct {
|
||||
* supported cipher.
|
||||
*/
|
||||
unsigned int cipher_mask();
|
||||
unsigned int cipher_mask1();
|
||||
unsigned int cipher_mask2();
|
||||
|
||||
/* Returns the name of the cipher. */
|
||||
const char *cipher_name(int cipher);
|
||||
@ -63,29 +80,36 @@ const char *cipher_name(int cipher);
|
||||
*/
|
||||
int cipher_number(const char *name);
|
||||
|
||||
/* returns 1 if all ciphers are supported (ssh2 only) */
|
||||
int ciphers_valid(const char *names);
|
||||
|
||||
/*
|
||||
* Selects the cipher to use and sets the key. If for_encryption is true,
|
||||
* the key is setup for encryption; otherwise it is setup for decryption.
|
||||
*/
|
||||
void
|
||||
void
|
||||
cipher_set_key(CipherContext * context, int cipher,
|
||||
const unsigned char *key, int keylen, int for_encryption);
|
||||
const unsigned char *key, int keylen);
|
||||
void
|
||||
cipher_set_key_iv(CipherContext * context, int cipher,
|
||||
const unsigned char *key, int keylen,
|
||||
const unsigned char *iv, int ivlen);
|
||||
|
||||
/*
|
||||
* Sets key for the cipher by computing the MD5 checksum of the passphrase,
|
||||
* and using the resulting 16 bytes as the key.
|
||||
*/
|
||||
void
|
||||
void
|
||||
cipher_set_key_string(CipherContext * context, int cipher,
|
||||
const char *passphrase, int for_encryption);
|
||||
const char *passphrase);
|
||||
|
||||
/* Encrypts data using the cipher. */
|
||||
void
|
||||
void
|
||||
cipher_encrypt(CipherContext * context, unsigned char *dest,
|
||||
const unsigned char *src, unsigned int len);
|
||||
|
||||
/* Decrypts data using the cipher. */
|
||||
void
|
||||
void
|
||||
cipher_decrypt(CipherContext * context, unsigned char *dest,
|
||||
const unsigned char *src, unsigned int len);
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: fingerprint.c,v 1.5 2000/03/16 20:56:14 markus Exp $");
|
||||
RCSID("$Id: fingerprint.c,v 1.6 2000/04/12 09:39:10 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* hostfile.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Thu Jun 29 07:10:56 1995 ylo
|
||||
*
|
||||
*
|
||||
* Functions for manipulating the known hosts files.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.14 2000/03/23 22:15:33 markus Exp $");
|
||||
RCSID("$OpenBSD: hostfile.c,v 1.18 2000/04/29 18:11:52 markus Exp $");
|
||||
|
||||
#include "packet.h"
|
||||
#include "match.h"
|
||||
@ -40,13 +40,8 @@ hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
|
||||
for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
|
||||
;
|
||||
|
||||
/* Get number of bits. */
|
||||
if (*cp < '0' || *cp > '9')
|
||||
return 0; /* Bad bit count... */
|
||||
for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
|
||||
bits = 10 * bits + *cp - '0';
|
||||
|
||||
if (!key_read(ret, bits, &cp))
|
||||
bits = key_read(ret, &cp);
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
|
||||
/* Skip trailing whitespace. */
|
||||
@ -76,10 +71,10 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i
|
||||
if (key == NULL || key->type != KEY_RSA || key->rsa == NULL)
|
||||
return 1;
|
||||
if (bits != BN_num_bits(key->rsa->n)) {
|
||||
error("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
log("Warning: %s, line %d: keysize mismatch for host %s: "
|
||||
"actual %d vs. announced %d.",
|
||||
filename, linenum, host, BN_num_bits(key->rsa->n), bits);
|
||||
error("Warning: replace %d with %d in %s, line %d.",
|
||||
log("Warning: replace %d with %d in %s, line %d.",
|
||||
bits, BN_num_bits(key->rsa->n), filename, linenum);
|
||||
}
|
||||
return 1;
|
||||
@ -183,24 +178,18 @@ add_host_to_hostfile(const char *filename, const char *host, Key *key)
|
||||
{
|
||||
FILE *f;
|
||||
int success = 0;
|
||||
|
||||
if (key == NULL)
|
||||
return 1;
|
||||
|
||||
/* Open the file for appending. */
|
||||
return 1; /* XXX ? */
|
||||
f = fopen(filename, "a");
|
||||
if (!f)
|
||||
return 0;
|
||||
|
||||
fprintf(f, "%s ", host);
|
||||
if (key_write(key, f)) {
|
||||
fprintf(f, "\n");
|
||||
success = 1;
|
||||
} else {
|
||||
error("add_host_to_hostfile: saving key failed");
|
||||
error("add_host_to_hostfile: saving key in %s failed", filename);
|
||||
}
|
||||
|
||||
/* Close the file. */
|
||||
fprintf(f, "\n");
|
||||
fclose(f);
|
||||
return success;
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* includes.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Thu Mar 23 16:29:37 1995 ylo
|
||||
*
|
||||
*
|
||||
* This file includes most of the needed system headers.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -63,34 +63,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
|
||||
/*
|
||||
* Define this to use pipes instead of socketpairs for communicating with the
|
||||
* client program. Socketpairs do not seem to work on all systems.
|
||||
* Although pipes are bi-directional in FreeBSD, using pipes here will
|
||||
* make <stdin> uni-directional !
|
||||
*/
|
||||
/* #define USE_PIPES 1 */
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ <= 3
|
||||
/*
|
||||
* Data types.
|
||||
*/
|
||||
typedef u_char sa_family_t;
|
||||
typedef u_int32_t socklen_t;
|
||||
|
||||
/*
|
||||
* bsd-api-new-02a: protocol-independent placeholder for socket addresses
|
||||
*/
|
||||
#define _SS_MAXSIZE 128
|
||||
#define _SS_ALIGNSIZE (sizeof(int64_t))
|
||||
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2)
|
||||
#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \
|
||||
_SS_PAD1SIZE - _SS_ALIGNSIZE)
|
||||
|
||||
struct sockaddr_storage {
|
||||
u_char ss_len; /* address length */
|
||||
sa_family_t ss_family; /* address family */
|
||||
char __ss_pad1[_SS_PAD1SIZE];
|
||||
int64_t __ss_align; /* force desired structure storage alignment */
|
||||
char __ss_pad2[_SS_PAD2SIZE];
|
||||
};
|
||||
#endif
|
||||
#define USE_PIPES 1
|
||||
|
||||
#endif /* INCLUDES_H */
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include <openssl/evp.h>
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "dsa.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#define SSH_DSS "ssh-dss"
|
||||
|
||||
Key *
|
||||
key_new(int type)
|
||||
@ -49,6 +53,8 @@ key_new(int type)
|
||||
DSA *dsa;
|
||||
k = xmalloc(sizeof(*k));
|
||||
k->type = type;
|
||||
k->dsa = NULL;
|
||||
k->rsa = NULL;
|
||||
switch (k->type) {
|
||||
case KEY_RSA:
|
||||
rsa = RSA_new();
|
||||
@ -65,8 +71,6 @@ key_new(int type)
|
||||
k->dsa = dsa;
|
||||
break;
|
||||
case KEY_EMPTY:
|
||||
k->dsa = NULL;
|
||||
k->rsa = NULL;
|
||||
break;
|
||||
default:
|
||||
fatal("key_new: bad key type %d", k->type);
|
||||
@ -113,7 +117,7 @@ key_equal(Key *a, Key *b)
|
||||
BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
|
||||
break;
|
||||
default:
|
||||
fatal("key_free: bad key type %d", a->type);
|
||||
fatal("key_equal: bad key type %d", a->type);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -129,46 +133,37 @@ char *
|
||||
key_fingerprint(Key *k)
|
||||
{
|
||||
static char retval[80];
|
||||
unsigned char *buf = NULL;
|
||||
unsigned char *blob = NULL;
|
||||
int len = 0;
|
||||
int nlen, elen, plen, qlen, glen, publen;
|
||||
int nlen, elen;
|
||||
|
||||
switch (k->type) {
|
||||
case KEY_RSA:
|
||||
nlen = BN_num_bytes(k->rsa->n);
|
||||
elen = BN_num_bytes(k->rsa->e);
|
||||
len = nlen + elen;
|
||||
buf = xmalloc(len);
|
||||
BN_bn2bin(k->rsa->n, buf);
|
||||
BN_bn2bin(k->rsa->e, buf + nlen);
|
||||
blob = xmalloc(len);
|
||||
BN_bn2bin(k->rsa->n, blob);
|
||||
BN_bn2bin(k->rsa->e, blob + nlen);
|
||||
break;
|
||||
case KEY_DSA:
|
||||
plen = BN_num_bytes(k->dsa->p);
|
||||
qlen = BN_num_bytes(k->dsa->q);
|
||||
glen = BN_num_bytes(k->dsa->g);
|
||||
publen = BN_num_bytes(k->dsa->pub_key);
|
||||
len = qlen + qlen + glen + publen;
|
||||
buf = xmalloc(len);
|
||||
BN_bn2bin(k->dsa->p, buf);
|
||||
BN_bn2bin(k->dsa->q, buf + plen);
|
||||
BN_bn2bin(k->dsa->g, buf + plen + qlen);
|
||||
BN_bn2bin(k->dsa->pub_key , buf + plen + qlen + glen);
|
||||
dsa_make_key_blob(k, &blob, &len);
|
||||
break;
|
||||
default:
|
||||
fatal("key_fingerprint: bad key type %d", k->type);
|
||||
break;
|
||||
}
|
||||
if (buf != NULL) {
|
||||
if (blob != NULL) {
|
||||
unsigned char d[16];
|
||||
EVP_MD_CTX md;
|
||||
EVP_DigestInit(&md, EVP_md5());
|
||||
EVP_DigestUpdate(&md, buf, len);
|
||||
EVP_DigestUpdate(&md, blob, len);
|
||||
EVP_DigestFinal(&md, d, NULL);
|
||||
snprintf(retval, sizeof(retval), FPRINT,
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||||
memset(buf, 0, len);
|
||||
xfree(buf);
|
||||
memset(blob, 0, len);
|
||||
xfree(blob);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@ -228,13 +223,27 @@ write_bignum(FILE *f, BIGNUM *num)
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
int
|
||||
key_read(Key *ret, unsigned int bits, char **cpp)
|
||||
unsigned int
|
||||
key_read(Key *ret, char **cpp)
|
||||
{
|
||||
Key *k;
|
||||
unsigned int bits = 0;
|
||||
char *cp;
|
||||
int len, n;
|
||||
unsigned char *blob;
|
||||
|
||||
cp = *cpp;
|
||||
|
||||
switch(ret->type) {
|
||||
case KEY_RSA:
|
||||
/* Get number of bits. */
|
||||
if (*cp < '0' || *cp > '9')
|
||||
return 0; /* Bad bit count... */
|
||||
for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
|
||||
bits = 10 * bits + *cp - '0';
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
*cpp = cp;
|
||||
/* Get public exponent, public modulus. */
|
||||
if (!read_bignum(cpp, ret->rsa->e))
|
||||
return 0;
|
||||
@ -242,22 +251,36 @@ key_read(Key *ret, unsigned int bits, char **cpp)
|
||||
return 0;
|
||||
break;
|
||||
case KEY_DSA:
|
||||
if (bits != 0)
|
||||
if (strncmp(cp, SSH_DSS " ", 7) != 0)
|
||||
return 0;
|
||||
if (!read_bignum(cpp, ret->dsa->p))
|
||||
cp += 7;
|
||||
len = 2*strlen(cp);
|
||||
blob = xmalloc(len);
|
||||
n = uudecode(cp, blob, len);
|
||||
if (n < 0) {
|
||||
error("uudecode %s failed", cp);
|
||||
return 0;
|
||||
if (!read_bignum(cpp, ret->dsa->q))
|
||||
return 0;
|
||||
if (!read_bignum(cpp, ret->dsa->g))
|
||||
return 0;
|
||||
if (!read_bignum(cpp, ret->dsa->pub_key))
|
||||
}
|
||||
k = dsa_key_from_blob(blob, n);
|
||||
if (k == NULL)
|
||||
return 0;
|
||||
xfree(blob);
|
||||
if (ret->dsa != NULL)
|
||||
DSA_free(ret->dsa);
|
||||
ret->dsa = k->dsa;
|
||||
k->dsa = NULL;
|
||||
key_free(k);
|
||||
bits = BN_num_bits(ret->dsa->p);
|
||||
cp = strchr(cp, '=');
|
||||
if (cp == NULL)
|
||||
return 0;
|
||||
*cpp = cp + 1;
|
||||
break;
|
||||
default:
|
||||
fatal("bad key type: %d", ret->type);
|
||||
fatal("key_read: bad key type: %d", ret->type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
return bits;
|
||||
}
|
||||
int
|
||||
key_write(Key *key, FILE *f)
|
||||
@ -276,17 +299,30 @@ key_write(Key *key, FILE *f)
|
||||
error("key_write: failed for RSA key");
|
||||
}
|
||||
} else if (key->type == KEY_DSA && key->dsa != NULL) {
|
||||
/* bits == 0 means DSA key */
|
||||
bits = 0;
|
||||
fprintf(f, "%u", bits);
|
||||
if (write_bignum(f, key->dsa->p) &&
|
||||
write_bignum(f, key->dsa->q) &&
|
||||
write_bignum(f, key->dsa->g) &&
|
||||
write_bignum(f, key->dsa->pub_key)) {
|
||||
int len, n;
|
||||
unsigned char *blob, *uu;
|
||||
dsa_make_key_blob(key, &blob, &len);
|
||||
uu = xmalloc(2*len);
|
||||
n = uuencode(blob, len, uu, 2*len);
|
||||
if (n > 0) {
|
||||
fprintf(f, "%s %s", SSH_DSS, uu);
|
||||
success = 1;
|
||||
} else {
|
||||
error("key_write: failed for DSA key");
|
||||
}
|
||||
xfree(blob);
|
||||
xfree(uu);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
char *
|
||||
key_type(Key *k)
|
||||
{
|
||||
switch (k->type) {
|
||||
case KEY_RSA:
|
||||
return "RSA";
|
||||
break;
|
||||
case KEY_DSA:
|
||||
return "DSA";
|
||||
break;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* login.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Fri Mar 24 14:51:08 1995 ylo
|
||||
*
|
||||
*
|
||||
* This file performs some of the things login(1) normally does. We cannot
|
||||
* easily use something like login -p -h host -f user, because there are
|
||||
* several different logins around, and it is hard to determined what kind of
|
||||
* login the current system has. Also, we want to be able to execute commands
|
||||
* on a tty.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: login.c,v 1.11 2000/01/04 00:07:59 markus Exp $");
|
||||
RCSID("$Id: login.c,v 1.13 2000/04/19 07:05:49 deraadt Exp $");
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <libutil.h>
|
||||
@ -40,7 +40,7 @@ RCSID("$Id: login.c,v 1.11 2000/01/04 00:07:59 markus Exp $");
|
||||
* is found). The name of the host used last time is returned in buf.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
unsigned long
|
||||
get_last_login_time(uid_t uid, const char *logname,
|
||||
char *buf, unsigned int bufsize)
|
||||
{
|
||||
@ -72,8 +72,8 @@ get_last_login_time(uid_t uid, const char *logname,
|
||||
* were more standardized.
|
||||
*/
|
||||
|
||||
void
|
||||
record_login(int pid, const char *ttyname, const char *user, uid_t uid,
|
||||
void
|
||||
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
const char *host, struct sockaddr * addr)
|
||||
{
|
||||
int fd;
|
||||
@ -120,8 +120,8 @@ record_login(int pid, const char *ttyname, const char *user, uid_t uid,
|
||||
|
||||
/* Records that the user has logged out. */
|
||||
|
||||
void
|
||||
record_logout(int pid, const char *ttyname)
|
||||
void
|
||||
record_logout(pid_t pid, const char *ttyname)
|
||||
{
|
||||
const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
|
||||
if (logout(line))
|
||||
|
@ -1,22 +1,22 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* mpaux.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Sun Jul 16 04:29:30 1995 ylo
|
||||
*
|
||||
*
|
||||
* This file contains various auxiliary functions related to multiple
|
||||
* precision integers.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: mpaux.c,v 1.9 1999/12/08 22:37:42 markus Exp $");
|
||||
RCSID("$Id: mpaux.c,v 1.12 2000/04/14 10:30:32 markus Exp $");
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include "getput.h"
|
||||
@ -26,9 +26,9 @@ RCSID("$Id: mpaux.c,v 1.9 1999/12/08 22:37:42 markus Exp $");
|
||||
|
||||
void
|
||||
compute_session_id(unsigned char session_id[16],
|
||||
unsigned char cookie[8],
|
||||
BIGNUM* host_key_n,
|
||||
BIGNUM* session_key_n)
|
||||
unsigned char cookie[8],
|
||||
BIGNUM* host_key_n,
|
||||
BIGNUM* session_key_n)
|
||||
{
|
||||
unsigned int host_key_bytes = BN_num_bytes(host_key_n);
|
||||
unsigned int session_key_bytes = BN_num_bytes(session_key_n);
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* packet.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Sat Mar 18 02:02:14 1995 ylo
|
||||
*
|
||||
*
|
||||
* Interface for the packet protocol functions.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: packet.h,v 1.10 2000/03/16 20:56:14 markus Exp $"); */
|
||||
/* RCSID("$Id: packet.h,v 1.15 2000/04/14 10:30:32 markus Exp $"); */
|
||||
|
||||
#ifndef PACKET_H
|
||||
#define PACKET_H
|
||||
@ -48,7 +48,7 @@ void packet_close(void);
|
||||
* key is used for both sending and reception. However, both directions are
|
||||
* encrypted independently of each other. Cipher types are defined in ssh.h.
|
||||
*/
|
||||
void
|
||||
void
|
||||
packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
|
||||
int cipher_type);
|
||||
|
||||
@ -84,9 +84,12 @@ void packet_put_int(unsigned int value);
|
||||
|
||||
/* Appends an arbitrary precision integer to packet data. */
|
||||
void packet_put_bignum(BIGNUM * value);
|
||||
void packet_put_bignum2(BIGNUM * value);
|
||||
|
||||
/* Appends a string to packet data. */
|
||||
void packet_put_string(const char *buf, unsigned int len);
|
||||
void packet_put_cstring(const char *str);
|
||||
void packet_put_raw(const char *buf, unsigned int len);
|
||||
|
||||
/*
|
||||
* Finalizes and sends the packet. If the encryption key has been set,
|
||||
@ -130,6 +133,8 @@ unsigned int packet_get_int(void);
|
||||
* must have been initialized before this call.
|
||||
*/
|
||||
void packet_get_bignum(BIGNUM * value, int *length_ptr);
|
||||
void packet_get_bignum2(BIGNUM * value, int *length_ptr);
|
||||
char *packet_get_raw(int *length_ptr);
|
||||
|
||||
/*
|
||||
* Returns a string from the packet data. The string is allocated using
|
||||
@ -192,8 +197,24 @@ do { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define packet_done() \
|
||||
do { \
|
||||
int _len = packet_remaining(); \
|
||||
if (_len > 0) { \
|
||||
log("Packet integrity error (%d bytes remaining) at %s:%d", \
|
||||
_len ,__FILE__, __LINE__); \
|
||||
packet_disconnect("Packet integrity error."); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* remote host is connected via a socket/ipv4 */
|
||||
int packet_connection_is_on_socket(void);
|
||||
int packet_connection_is_ipv4(void);
|
||||
|
||||
/* enable SSH2 packet format */
|
||||
void packet_set_ssh2_format(void);
|
||||
|
||||
/* returns remaining payload bytes */
|
||||
int packet_remaining(void);
|
||||
|
||||
#endif /* PACKET_H */
|
||||
|
@ -1,27 +1,27 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* pty.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Fri Mar 17 04:37:25 1995 ylo
|
||||
*
|
||||
*
|
||||
* Allocating a pseudo-terminal, and making it the controlling tty.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: pty.c,v 1.12 2000/02/15 16:52:58 markus Exp $");
|
||||
RCSID("$Id: pty.c,v 1.13 2000/04/14 10:30:32 markus Exp $");
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <libutil.h>
|
||||
#else
|
||||
#include <util.h>
|
||||
#endif
|
||||
#endif /* __FreeBSD__ */
|
||||
#include "pty.h"
|
||||
#include "ssh.h"
|
||||
|
||||
@ -41,7 +41,7 @@ RCSID("$Id: pty.c,v 1.12 2000/02/15 16:52:58 markus Exp $");
|
||||
* returned (the buffer must be able to hold at least 64 characters).
|
||||
*/
|
||||
|
||||
int
|
||||
int
|
||||
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
{
|
||||
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
|
||||
@ -179,7 +179,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
|
||||
/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */
|
||||
|
||||
void
|
||||
void
|
||||
pty_release(const char *ttyname)
|
||||
{
|
||||
if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0)
|
||||
@ -190,7 +190,7 @@ pty_release(const char *ttyname)
|
||||
|
||||
/* Makes the tty the processes controlling tty and sets it to sane modes. */
|
||||
|
||||
void
|
||||
void
|
||||
pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
{
|
||||
int fd;
|
||||
@ -243,7 +243,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
|
||||
/* Changes the window size associated with the pty. */
|
||||
|
||||
void
|
||||
void
|
||||
pty_change_window_size(int ptyfd, int row, int col,
|
||||
int xpixel, int ypixel)
|
||||
{
|
||||
|
@ -1,26 +1,28 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* readconf.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Sat Apr 22 00:03:10 1995 ylo
|
||||
*
|
||||
*
|
||||
* Functions for reading the configuration files.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: readconf.c,v 1.23 2000/02/28 19:51:58 markus Exp $");
|
||||
RCSID("$Id: readconf.c,v 1.31 2000/05/08 17:12:15 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "cipher.h"
|
||||
#include "readconf.h"
|
||||
#include "match.h"
|
||||
#include "xmalloc.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* Format of the configuration file:
|
||||
|
||||
@ -106,7 +108,8 @@ typedef enum {
|
||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
|
||||
oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
|
||||
oUsePrivilegedPort, oLogLevel
|
||||
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2,
|
||||
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication
|
||||
} OpCodes;
|
||||
|
||||
/* Textual representations of the tokens. */
|
||||
@ -122,6 +125,7 @@ static struct {
|
||||
{ "rhostsauthentication", oRhostsAuthentication },
|
||||
{ "passwordauthentication", oPasswordAuthentication },
|
||||
{ "rsaauthentication", oRSAAuthentication },
|
||||
{ "dsaauthentication", oDSAAuthentication },
|
||||
{ "skeyauthentication", oSkeyAuthentication },
|
||||
#ifdef KRB4
|
||||
{ "kerberos4authentication", oKrb4Authentication },
|
||||
@ -137,10 +141,13 @@ static struct {
|
||||
{ "fallbacktorsh", oFallBackToRsh },
|
||||
{ "usersh", oUseRsh },
|
||||
{ "identityfile", oIdentityFile },
|
||||
{ "identityfile2", oIdentityFile2 },
|
||||
{ "hostname", oHostName },
|
||||
{ "proxycommand", oProxyCommand },
|
||||
{ "port", oPort },
|
||||
{ "cipher", oCipher },
|
||||
{ "ciphers", oCiphers },
|
||||
{ "protocol", oProtocol },
|
||||
{ "remoteforward", oRemoteForward },
|
||||
{ "localforward", oLocalForward },
|
||||
{ "user", oUser },
|
||||
@ -149,6 +156,8 @@ static struct {
|
||||
{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
|
||||
{ "globalknownhostsfile", oGlobalKnownHostsFile },
|
||||
{ "userknownhostsfile", oUserKnownHostsFile },
|
||||
{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },
|
||||
{ "userknownhostsfile2", oUserKnownHostsFile2 },
|
||||
{ "connectionattempts", oConnectionAttempts },
|
||||
{ "batchmode", oBatchMode },
|
||||
{ "checkhostip", oCheckHostIP },
|
||||
@ -171,7 +180,7 @@ static struct {
|
||||
* error.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
add_local_forward(Options *options, u_short port, const char *host,
|
||||
u_short host_port)
|
||||
{
|
||||
@ -192,7 +201,7 @@ add_local_forward(Options *options, u_short port, const char *host,
|
||||
* an error.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
add_remote_forward(Options *options, u_short port, const char *host,
|
||||
u_short host_port)
|
||||
{
|
||||
@ -211,7 +220,7 @@ add_remote_forward(Options *options, u_short port, const char *host,
|
||||
* returns if the token is not known.
|
||||
*/
|
||||
|
||||
static OpCodes
|
||||
static OpCodes
|
||||
parse_token(const char *cp, const char *filename, int linenum)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -290,6 +299,10 @@ process_config_line(Options *options, const char *host,
|
||||
intptr = &options->password_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oDSAAuthentication:
|
||||
intptr = &options->dsa_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case oRSAAuthentication:
|
||||
intptr = &options->rsa_authentication;
|
||||
goto parse_flag;
|
||||
@ -382,14 +395,22 @@ process_config_line(Options *options, const char *host,
|
||||
goto parse_int;
|
||||
|
||||
case oIdentityFile:
|
||||
case oIdentityFile2:
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!cp)
|
||||
fatal("%.200s line %d: Missing argument.", filename, linenum);
|
||||
if (*activep) {
|
||||
if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
|
||||
intptr = (opcode == oIdentityFile) ?
|
||||
&options->num_identity_files :
|
||||
&options->num_identity_files2;
|
||||
if (*intptr >= SSH_MAX_IDENTITY_FILES)
|
||||
fatal("%.200s line %d: Too many identity files specified (max %d).",
|
||||
filename, linenum, SSH_MAX_IDENTITY_FILES);
|
||||
options->identity_files[options->num_identity_files++] = xstrdup(cp);
|
||||
charptr = (opcode == oIdentityFile) ?
|
||||
&options->identity_files[*intptr] :
|
||||
&options->identity_files2[*intptr];
|
||||
*charptr = xstrdup(cp);
|
||||
*intptr = *intptr + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -411,6 +432,14 @@ process_config_line(Options *options, const char *host,
|
||||
charptr = &options->user_hostfile;
|
||||
goto parse_string;
|
||||
|
||||
case oGlobalKnownHostsFile2:
|
||||
charptr = &options->system_hostfile2;
|
||||
goto parse_string;
|
||||
|
||||
case oUserKnownHostsFile2:
|
||||
charptr = &options->user_hostfile2;
|
||||
goto parse_string;
|
||||
|
||||
case oHostName:
|
||||
charptr = &options->hostname;
|
||||
goto parse_string;
|
||||
@ -461,6 +490,26 @@ process_config_line(Options *options, const char *host,
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oCiphers:
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!ciphers_valid(cp))
|
||||
fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
if (*activep && options->ciphers == NULL)
|
||||
options->ciphers = xstrdup(cp);
|
||||
break;
|
||||
|
||||
case oProtocol:
|
||||
intptr = &options->protocol;
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
value = proto_spec(cp);
|
||||
if (value == SSH_PROTO_UNKNOWN)
|
||||
fatal("%.200s line %d: Bad protocol spec '%s'.",
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
if (*activep && *intptr == SSH_PROTO_UNKNOWN)
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oLogLevel:
|
||||
intptr = (int *) &options->log_level;
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
@ -561,7 +610,7 @@ process_config_line(Options *options, const char *host,
|
||||
* there is an error. If the file does not exist, this returns immediately.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
read_config_file(const char *filename, const char *host, Options *options)
|
||||
{
|
||||
FILE *f;
|
||||
@ -601,7 +650,7 @@ read_config_file(const char *filename, const char *host, Options *options)
|
||||
* system config file. Last, fill_default_options is called.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
initialize_options(Options * options)
|
||||
{
|
||||
memset(options, 'X', sizeof(*options));
|
||||
@ -611,6 +660,7 @@ initialize_options(Options * options)
|
||||
options->use_privileged_port = -1;
|
||||
options->rhosts_authentication = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->dsa_authentication = -1;
|
||||
options->skey_authentication = -1;
|
||||
#ifdef KRB4
|
||||
options->krb4_authentication = -1;
|
||||
@ -637,13 +687,18 @@ initialize_options(Options * options)
|
||||
options->connection_attempts = -1;
|
||||
options->number_of_password_prompts = -1;
|
||||
options->cipher = -1;
|
||||
options->ciphers = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->num_identity_files = 0;
|
||||
options->num_identity_files2 = 0;
|
||||
options->hostname = NULL;
|
||||
options->proxy_command = NULL;
|
||||
options->user = NULL;
|
||||
options->escape_char = -1;
|
||||
options->system_hostfile = NULL;
|
||||
options->user_hostfile = NULL;
|
||||
options->system_hostfile2 = NULL;
|
||||
options->user_hostfile2 = NULL;
|
||||
options->num_local_forwards = 0;
|
||||
options->num_remote_forwards = 0;
|
||||
options->log_level = (LogLevel) - 1;
|
||||
@ -654,7 +709,7 @@ initialize_options(Options * options)
|
||||
* options for which no value has been specified with their default values.
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
fill_default_options(Options * options)
|
||||
{
|
||||
if (options->forward_agent == -1)
|
||||
@ -669,6 +724,8 @@ fill_default_options(Options * options)
|
||||
options->rhosts_authentication = 1;
|
||||
if (options->rsa_authentication == -1)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->dsa_authentication == -1)
|
||||
options->dsa_authentication = 1;
|
||||
if (options->skey_authentication == -1)
|
||||
options->skey_authentication = 0;
|
||||
#ifdef KRB4
|
||||
@ -716,18 +773,31 @@ fill_default_options(Options * options)
|
||||
/* Selected in ssh_login(). */
|
||||
if (options->cipher == -1)
|
||||
options->cipher = SSH_CIPHER_NOT_SET;
|
||||
/* options->ciphers, default set in myproposals.h */
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
|
||||
if (options->num_identity_files == 0) {
|
||||
options->identity_files[0] =
|
||||
xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
|
||||
sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
|
||||
options->num_identity_files = 1;
|
||||
}
|
||||
if (options->num_identity_files2 == 0) {
|
||||
options->identity_files2[0] =
|
||||
xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
|
||||
sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA);
|
||||
options->num_identity_files2 = 1;
|
||||
}
|
||||
if (options->escape_char == -1)
|
||||
options->escape_char = '~';
|
||||
if (options->system_hostfile == NULL)
|
||||
options->system_hostfile = SSH_SYSTEM_HOSTFILE;
|
||||
if (options->user_hostfile == NULL)
|
||||
options->user_hostfile = SSH_USER_HOSTFILE;
|
||||
if (options->system_hostfile2 == NULL)
|
||||
options->system_hostfile2 = SSH_SYSTEM_HOSTFILE2;
|
||||
if (options->user_hostfile2 == NULL)
|
||||
options->user_hostfile2 = SSH_USER_HOSTFILE2;
|
||||
if (options->log_level == (LogLevel) - 1)
|
||||
options->log_level = SYSLOG_LEVEL_INFO;
|
||||
/* options->proxy_command should not be set by default */
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* readconf.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Sat Apr 22 00:25:29 1995 ylo
|
||||
*
|
||||
*
|
||||
* Functions for reading the configuration file.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: readconf.h,v 1.13 1999/12/01 13:59:15 markus Exp $"); */
|
||||
/* RCSID("$Id: readconf.h,v 1.18 2000/05/08 17:12:15 markus Exp $"); */
|
||||
|
||||
#ifndef READCONF_H
|
||||
#define READCONF_H
|
||||
@ -37,6 +37,7 @@ typedef struct {
|
||||
int rhosts_rsa_authentication; /* Try rhosts with RSA
|
||||
* authentication. */
|
||||
int rsa_authentication; /* Try RSA authentication. */
|
||||
int dsa_authentication; /* Try DSA authentication. */
|
||||
int skey_authentication; /* Try S/Key or TIS authentication. */
|
||||
#ifdef KRB4
|
||||
int krb4_authentication; /* Try Kerberos v4
|
||||
@ -71,6 +72,8 @@ typedef struct {
|
||||
int number_of_password_prompts; /* Max number of password
|
||||
* prompts. */
|
||||
int cipher; /* Cipher to use. */
|
||||
char *ciphers; /* SSH2 ciphers in order of preference. */
|
||||
int protocol; /* Protocol in order of preference. */
|
||||
char *hostname; /* Real host to connect. */
|
||||
char *proxy_command; /* Proxy command for connecting the host. */
|
||||
char *user; /* User to log in as. */
|
||||
@ -78,9 +81,13 @@ typedef struct {
|
||||
|
||||
char *system_hostfile;/* Path for /etc/ssh_known_hosts. */
|
||||
char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */
|
||||
char *system_hostfile2;
|
||||
char *user_hostfile2;
|
||||
|
||||
int num_identity_files; /* Number of files for RSA identities. */
|
||||
int num_identity_files2; /* DSA identities. */
|
||||
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
||||
char *identity_files2[SSH_MAX_IDENTITY_FILES];
|
||||
|
||||
/* Local TCP/IP forward requests. */
|
||||
int num_local_forwards;
|
||||
@ -111,7 +118,7 @@ void fill_default_options(Options * options);
|
||||
* only sets those values that have not already been set. Returns 0 for legal
|
||||
* options
|
||||
*/
|
||||
int
|
||||
int
|
||||
process_config_line(Options * options, const char *host,
|
||||
char *line, const char *filename, int linenum,
|
||||
int *activep);
|
||||
@ -121,7 +128,7 @@ process_config_line(Options * options, const char *host,
|
||||
* should already be initialized before this call. This never returns if
|
||||
* there is an error. If the file does not exist, this returns immediately.
|
||||
*/
|
||||
void
|
||||
void
|
||||
read_config_file(const char *filename, const char *host,
|
||||
Options * options);
|
||||
|
||||
@ -129,7 +136,7 @@ read_config_file(const char *filename, const char *host,
|
||||
* Adds a local TCP/IP port forward to options. Never returns if there is an
|
||||
* error.
|
||||
*/
|
||||
void
|
||||
void
|
||||
add_local_forward(Options * options, u_short port, const char *host,
|
||||
u_short host_port);
|
||||
|
||||
@ -137,7 +144,7 @@ add_local_forward(Options * options, u_short port, const char *host,
|
||||
* Adds a remote TCP/IP port forward to options. Never returns if there is
|
||||
* an error.
|
||||
*/
|
||||
void
|
||||
void
|
||||
add_remote_forward(Options * options, u_short port, const char *host,
|
||||
u_short host_port);
|
||||
|
||||
|
@ -1,43 +1,42 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* rsa.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Fri Mar 3 22:07:06 1995 ylo
|
||||
*
|
||||
*
|
||||
* Description of the RSA algorithm can be found e.g. from the following sources:
|
||||
*
|
||||
*
|
||||
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994.
|
||||
*
|
||||
*
|
||||
* Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to
|
||||
* Computer Security. Prentice-Hall, 1989.
|
||||
*
|
||||
*
|
||||
* Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill,
|
||||
* 1994.
|
||||
*
|
||||
*
|
||||
* R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications
|
||||
* System and Method. US Patent 4,405,829, 1983.
|
||||
*
|
||||
*
|
||||
* Hans Riesel: Prime Numbers and Computer Methods for Factorization.
|
||||
* Birkhauser, 1994.
|
||||
*
|
||||
*
|
||||
* The RSA Frequently Asked Questions document by RSA Data Security, Inc., 1995.
|
||||
*
|
||||
*
|
||||
* RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as included
|
||||
* below:
|
||||
*
|
||||
*
|
||||
* [gone - had to be deleted - what a pity]
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: rsa.c,v 1.13 2000/03/16 20:56:14 markus Exp $");
|
||||
RCSID("$Id: rsa.c,v 1.14 2000/04/14 10:30:32 markus Exp $");
|
||||
|
||||
#include "rsa.h"
|
||||
#include "ssh.h"
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* rsa.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Fri Mar 3 22:01:06 1995 ylo
|
||||
*
|
||||
*
|
||||
* RSA key generation, encryption and decryption.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: rsa.h,v 1.4 1999/11/24 19:53:50 markus Exp $"); */
|
||||
/* RCSID("$Id: rsa.h,v 1.6 2000/04/14 10:30:32 markus Exp $"); */
|
||||
|
||||
#ifndef RSA_H
|
||||
#define RSA_H
|
||||
|
@ -1,30 +1,31 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* servconf.c
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Mon Aug 21 15:48:58 1995 ylo
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: servconf.c,v 1.31 2000/03/07 20:40:41 markus Exp $");
|
||||
RCSID("$Id: servconf.c,v 1.40 2000/05/08 17:12:15 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "servconf.h"
|
||||
#include "xmalloc.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* add listen address */
|
||||
void add_listen_addr(ServerOptions *options, char *addr);
|
||||
|
||||
/* Initializes the server options to their default values. */
|
||||
|
||||
void
|
||||
void
|
||||
initialize_server_options(ServerOptions *options)
|
||||
{
|
||||
memset(options, 0, sizeof(*options));
|
||||
@ -32,6 +33,8 @@ initialize_server_options(ServerOptions *options)
|
||||
options->ports_from_cmdline = 0;
|
||||
options->listen_addrs = NULL;
|
||||
options->host_key_file = NULL;
|
||||
options->host_dsa_key_file = NULL;
|
||||
options->pid_file = NULL;
|
||||
options->server_key_bits = -1;
|
||||
options->login_grace_time = -1;
|
||||
options->key_regeneration_time = -1;
|
||||
@ -49,6 +52,7 @@ initialize_server_options(ServerOptions *options)
|
||||
options->rhosts_authentication = -1;
|
||||
options->rhosts_rsa_authentication = -1;
|
||||
options->rsa_authentication = -1;
|
||||
options->dsa_authentication = -1;
|
||||
#ifdef KRB4
|
||||
options->krb4_authentication = -1;
|
||||
options->krb4_or_local_passwd = -1;
|
||||
@ -72,11 +76,14 @@ initialize_server_options(ServerOptions *options)
|
||||
options->num_deny_users = 0;
|
||||
options->num_allow_groups = 0;
|
||||
options->num_deny_groups = 0;
|
||||
options->ciphers = NULL;
|
||||
options->protocol = SSH_PROTO_UNKNOWN;
|
||||
options->gateway_ports = -1;
|
||||
options->connections_per_period = 0;
|
||||
options->connections_period = 0;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
fill_default_server_options(ServerOptions *options)
|
||||
{
|
||||
if (options->num_ports == 0)
|
||||
@ -85,6 +92,10 @@ fill_default_server_options(ServerOptions *options)
|
||||
add_listen_addr(options, NULL);
|
||||
if (options->host_key_file == NULL)
|
||||
options->host_key_file = HOST_KEY_FILE;
|
||||
if (options->host_dsa_key_file == NULL)
|
||||
options->host_dsa_key_file = HOST_DSA_KEY_FILE;
|
||||
if (options->pid_file == NULL)
|
||||
options->pid_file = SSH_DAEMON_PID_FILE;
|
||||
if (options->server_key_bits == -1)
|
||||
options->server_key_bits = 768;
|
||||
if (options->login_grace_time == -1)
|
||||
@ -119,6 +130,8 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->rhosts_rsa_authentication = 0;
|
||||
if (options->rsa_authentication == -1)
|
||||
options->rsa_authentication = 1;
|
||||
if (options->dsa_authentication == -1)
|
||||
options->dsa_authentication = 1;
|
||||
#ifdef KRB4
|
||||
if (options->krb4_authentication == -1)
|
||||
options->krb4_authentication = (access(KEYFILE, R_OK) == 0);
|
||||
@ -149,6 +162,10 @@ fill_default_server_options(ServerOptions *options)
|
||||
options->permit_empty_passwd = 0;
|
||||
if (options->use_login == -1)
|
||||
options->use_login = 0;
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_1|SSH_PROTO_2;
|
||||
if (options->gateway_ports == -1)
|
||||
options->gateway_ports = 0;
|
||||
}
|
||||
|
||||
#define WHITESPACE " \t\r\n"
|
||||
@ -175,7 +192,8 @@ typedef enum {
|
||||
sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
|
||||
sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
|
||||
sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
|
||||
sIgnoreUserKnownHosts, sConnectionsPerPeriod
|
||||
sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
|
||||
sGatewayPorts, sDSAAuthentication, sConnectionsPerPeriod
|
||||
} ServerOpCodes;
|
||||
|
||||
/* Textual representation of the tokens. */
|
||||
@ -185,6 +203,8 @@ static struct {
|
||||
} keywords[] = {
|
||||
{ "port", sPort },
|
||||
{ "hostkey", sHostKeyFile },
|
||||
{ "hostdsakey", sHostDSAKeyFile },
|
||||
{ "pidfile", sPidFile },
|
||||
{ "serverkeybits", sServerKeyBits },
|
||||
{ "logingracetime", sLoginGraceTime },
|
||||
{ "keyregenerationinterval", sKeyRegenerationTime },
|
||||
@ -194,6 +214,7 @@ static struct {
|
||||
{ "rhostsauthentication", sRhostsAuthentication },
|
||||
{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
|
||||
{ "rsaauthentication", sRSAAuthentication },
|
||||
{ "dsaauthentication", sDSAAuthentication },
|
||||
#ifdef KRB4
|
||||
{ "kerberos4authentication", sKrb4Authentication },
|
||||
{ "kerberos4orlocalpasswd", sKrb4OrLocalPasswd },
|
||||
@ -227,6 +248,9 @@ static struct {
|
||||
{ "denyusers", sDenyUsers },
|
||||
{ "allowgroups", sAllowGroups },
|
||||
{ "denygroups", sDenyGroups },
|
||||
{ "ciphers", sCiphers },
|
||||
{ "protocol", sProtocol },
|
||||
{ "gatewayports", sGatewayPorts },
|
||||
{ "connectionsperperiod", sConnectionsPerPeriod },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
@ -236,7 +260,7 @@ static struct {
|
||||
* returns if the token is not known.
|
||||
*/
|
||||
|
||||
static ServerOpCodes
|
||||
static ServerOpCodes
|
||||
parse_token(const char *cp, const char *filename,
|
||||
int linenum)
|
||||
{
|
||||
@ -254,7 +278,7 @@ parse_token(const char *cp, const char *filename,
|
||||
/*
|
||||
* add listen address
|
||||
*/
|
||||
void
|
||||
void
|
||||
add_listen_addr(ServerOptions *options, char *addr)
|
||||
{
|
||||
extern int IPv4or6;
|
||||
@ -284,7 +308,7 @@ add_listen_addr(ServerOptions *options, char *addr)
|
||||
|
||||
/* Reads the server configuration file. */
|
||||
|
||||
void
|
||||
void
|
||||
read_server_config(ServerOptions *options, const char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
@ -320,7 +344,7 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
"ListenAdress.\n", filename, linenum);
|
||||
if (options->num_ports >= MAX_PORTS)
|
||||
fatal("%s line %d: too many ports.\n",
|
||||
filename, linenum);
|
||||
filename, linenum);
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!cp)
|
||||
fatal("%s line %d: missing port number.\n",
|
||||
@ -363,11 +387,25 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
break;
|
||||
|
||||
case sHostKeyFile:
|
||||
charptr = &options->host_key_file;
|
||||
case sHostDSAKeyFile:
|
||||
charptr = (opcode == sHostKeyFile ) ?
|
||||
&options->host_key_file : &options->host_dsa_key_file;
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!cp) {
|
||||
fprintf(stderr, "%s line %d: missing file name.\n",
|
||||
filename, linenum);
|
||||
filename, linenum);
|
||||
exit(1);
|
||||
}
|
||||
if (*charptr == NULL)
|
||||
*charptr = tilde_expand_filename(cp, getuid());
|
||||
break;
|
||||
|
||||
case sPidFile:
|
||||
charptr = &options->pid_file;
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!cp) {
|
||||
fprintf(stderr, "%s line %d: missing file name.\n",
|
||||
filename, linenum);
|
||||
exit(1);
|
||||
}
|
||||
if (*charptr == NULL)
|
||||
@ -441,6 +479,10 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
intptr = &options->rsa_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
case sDSAAuthentication:
|
||||
intptr = &options->dsa_authentication;
|
||||
goto parse_flag;
|
||||
|
||||
#ifdef KRB4
|
||||
case sKrb4Authentication:
|
||||
intptr = &options->krb4_authentication;
|
||||
@ -517,13 +559,17 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
intptr = &options->use_login;
|
||||
goto parse_flag;
|
||||
|
||||
case sGatewayPorts:
|
||||
intptr = &options->gateway_ports;
|
||||
goto parse_flag;
|
||||
|
||||
case sLogFacility:
|
||||
intptr = (int *) &options->log_facility;
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
value = log_facility_number(cp);
|
||||
if (value == (SyslogFacility) - 1)
|
||||
fatal("%.200s line %d: unsupported log facility '%s'\n",
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
if (*intptr == -1)
|
||||
*intptr = (SyslogFacility) value;
|
||||
break;
|
||||
@ -534,7 +580,7 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
value = log_level_number(cp);
|
||||
if (value == (LogLevel) - 1)
|
||||
fatal("%.200s line %d: unsupported log level '%s'\n",
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
if (*intptr == -1)
|
||||
*intptr = (LogLevel) value;
|
||||
break;
|
||||
@ -542,17 +588,16 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
case sAllowUsers:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_allow_users >= MAX_ALLOW_USERS)
|
||||
fatal("%.200s line %d: too many allow users.\n", filename,
|
||||
linenum);
|
||||
fatal("%.200s line %d: too many allow users.\n",
|
||||
filename, linenum);
|
||||
options->allow_users[options->num_allow_users++] = xstrdup(cp);
|
||||
}
|
||||
break;
|
||||
|
||||
case sDenyUsers:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_deny_users >= MAX_DENY_USERS)
|
||||
fatal("%.200s line %d: too many deny users.\n", filename,
|
||||
linenum);
|
||||
fatal("%.200s line %d: too many deny users.\n",
|
||||
filename, linenum);
|
||||
options->deny_users[options->num_deny_users++] = xstrdup(cp);
|
||||
}
|
||||
break;
|
||||
@ -560,8 +605,8 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
case sAllowGroups:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
|
||||
fatal("%.200s line %d: too many allow groups.\n", filename,
|
||||
linenum);
|
||||
fatal("%.200s line %d: too many allow groups.\n",
|
||||
filename, linenum);
|
||||
options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
|
||||
}
|
||||
break;
|
||||
@ -569,12 +614,32 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
case sDenyGroups:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_deny_groups >= MAX_DENY_GROUPS)
|
||||
fatal("%.200s line %d: too many deny groups.\n", filename,
|
||||
linenum);
|
||||
fatal("%.200s line %d: too many deny groups.\n",
|
||||
filename, linenum);
|
||||
options->deny_groups[options->num_deny_groups++] = xstrdup(cp);
|
||||
}
|
||||
break;
|
||||
|
||||
case sCiphers:
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!ciphers_valid(cp))
|
||||
fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
if (options->ciphers == NULL)
|
||||
options->ciphers = xstrdup(cp);
|
||||
break;
|
||||
|
||||
case sProtocol:
|
||||
intptr = &options->protocol;
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
value = proto_spec(cp);
|
||||
if (value == SSH_PROTO_UNKNOWN)
|
||||
fatal("%s line %d: Bad protocol spec '%s'.",
|
||||
filename, linenum, cp ? cp : "<NONE>");
|
||||
if (*intptr == SSH_PROTO_UNKNOWN)
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case sConnectionsPerPeriod:
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (cp == NULL)
|
||||
@ -594,12 +659,14 @@ read_server_config(ServerOptions *options, const char *filename)
|
||||
fatal("%.200s line %d: Missing handler for opcode %s (%d)\n",
|
||||
filename, linenum, cp, opcode);
|
||||
}
|
||||
if (strtok(NULL, WHITESPACE) != NULL)
|
||||
fatal("%.200s line %d: garbage at end of line.\n", filename,
|
||||
linenum);
|
||||
if (strtok(NULL, WHITESPACE) != NULL) {
|
||||
fatal("%.200s line %d: garbage at end of line.\n",
|
||||
filename, linenum);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
if (bad_options > 0)
|
||||
if (bad_options > 0) {
|
||||
fatal("%.200s: terminating, %d bad configuration options\n",
|
||||
filename, bad_options);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* servconf.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Mon Aug 21 15:35:03 1995 ylo
|
||||
*
|
||||
*
|
||||
* Definitions for server configuration data and for the functions reading it.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: servconf.h,v 1.15 2000/01/04 00:08:00 markus Exp $"); */
|
||||
/* RCSID("$Id: servconf.h,v 1.22 2000/05/06 17:45:37 markus Exp $"); */
|
||||
|
||||
#ifndef SERVCONF_H
|
||||
#define SERVCONF_H
|
||||
@ -33,6 +33,8 @@ typedef struct {
|
||||
char *listen_addr; /* Address on which the server listens. */
|
||||
struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
|
||||
char *host_key_file; /* File containing host key. */
|
||||
char *host_dsa_key_file; /* File containing dsa host key. */
|
||||
char *pid_file; /* Where to put our pid */
|
||||
int server_key_bits;/* Size of the server key. */
|
||||
int login_grace_time; /* Disconnect if no auth in this time
|
||||
* (sec). */
|
||||
@ -48,6 +50,9 @@ typedef struct {
|
||||
* searching at */
|
||||
int strict_modes; /* If true, require string home dir modes. */
|
||||
int keepalives; /* If true, set SO_KEEPALIVE. */
|
||||
char *ciphers; /* Ciphers in order of preference. */
|
||||
int protocol; /* Protocol in order of preference. */
|
||||
int gateway_ports; /* If true, allow remote connects to forwarded ports. */
|
||||
SyslogFacility log_facility; /* Facility for system logging. */
|
||||
LogLevel log_level; /* Level for system logging. */
|
||||
int rhosts_authentication; /* If true, permit rhosts
|
||||
@ -55,6 +60,7 @@ typedef struct {
|
||||
int rhosts_rsa_authentication; /* If true, permit rhosts RSA
|
||||
* authentication. */
|
||||
int rsa_authentication; /* If true, permit RSA authentication. */
|
||||
int dsa_authentication; /* If true, permit DSA authentication. */
|
||||
#ifdef KRB4
|
||||
int krb4_authentication; /* If true, permit Kerberos v4
|
||||
* authentication. */
|
||||
|
@ -5,6 +5,8 @@
|
||||
/*
|
||||
* SSH2 support by Markus Friedl.
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@ -27,6 +29,15 @@ RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $");
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define LOGIN_CAP
|
||||
#define _PATH_CHPASS "/usr/bin/passwd"
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
/* types */
|
||||
|
||||
#define TTYSZ 64
|
||||
@ -504,6 +515,15 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
||||
struct sockaddr_storage from;
|
||||
struct stat st;
|
||||
time_t last_login_time;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
char *fname;
|
||||
#endif /* LOGIN_CAP */
|
||||
#ifdef __FreeBSD__
|
||||
#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
|
||||
struct timeval tv;
|
||||
time_t warntime = DEFAULT_WARN;
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
if (s == NULL)
|
||||
fatal("do_exec_pty: no session");
|
||||
@ -574,6 +594,66 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
||||
snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
|
||||
quiet_login = stat(line, &st) >= 0;
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
lc = login_getpwclass(pw);
|
||||
if (lc == NULL)
|
||||
lc = login_getclassbyname(NULL, pw);
|
||||
quiet_login = login_getcapbool(lc, "hushlogin", quiet_login);
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (pw->pw_change || pw->pw_expire)
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
#ifdef LOGIN_CAP
|
||||
warntime = login_getcaptime(lc, "warnpassword",
|
||||
DEFAULT_WARN, DEFAULT_WARN);
|
||||
#endif /* LOGIN_CAP */
|
||||
/*
|
||||
* If the password change time is set and has passed, give the
|
||||
* user a password expiry notice and chance to change it.
|
||||
*/
|
||||
if (pw->pw_change != 0) {
|
||||
if (tv.tv_sec >= pw->pw_change) {
|
||||
(void)printf(
|
||||
"Sorry -- your password has expired.\n");
|
||||
log("%s Password expired - forcing change",
|
||||
pw->pw_name);
|
||||
command = _PATH_CHPASS;
|
||||
} else if (pw->pw_change - tv.tv_sec < warntime &&
|
||||
!quiet_login)
|
||||
(void)printf(
|
||||
"Warning: your password expires on %s",
|
||||
ctime(&pw->pw_change));
|
||||
}
|
||||
#ifdef LOGIN_CAP
|
||||
warntime = login_getcaptime(lc, "warnexpire",
|
||||
DEFAULT_WARN, DEFAULT_WARN);
|
||||
#endif /* LOGIN_CAP */
|
||||
if (pw->pw_expire) {
|
||||
if (tv.tv_sec >= pw->pw_expire) {
|
||||
(void)printf(
|
||||
"Sorry -- your account has expired.\n");
|
||||
log(
|
||||
"LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
|
||||
pw->pw_name, hostname, ttyname);
|
||||
exit(254);
|
||||
} else if (pw->pw_expire - tv.tv_sec < warntime &&
|
||||
!quiet_login)
|
||||
(void)printf(
|
||||
"Warning: your account expires on %s",
|
||||
ctime(&pw->pw_expire));
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
#ifdef LOGIN_CAP
|
||||
if (!auth_ttyok(lc, ttyname)) {
|
||||
(void)printf("Permission denied.\n");
|
||||
log(
|
||||
"LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s",
|
||||
pw->pw_name, hostname, ttyname);
|
||||
exit(254);
|
||||
}
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
/*
|
||||
* If the user has logged in before, display the time of last
|
||||
* login. However, don't display anything extra if a command
|
||||
@ -596,6 +676,22 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
||||
else
|
||||
printf("Last login: %s from %s\r\n", time_string, buf);
|
||||
}
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if (command == NULL && !quiet_login && !options.use_login) {
|
||||
fname = login_getcapstr(lc, "copyright", NULL, NULL);
|
||||
if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
|
||||
while (fgets(line, sizeof(line), f) != NULL)
|
||||
fputs(line, stdout);
|
||||
fclose(f);
|
||||
} else
|
||||
(void)printf("%s\n\t%s %s\n",
|
||||
"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
|
||||
"The Regents of the University of California. ",
|
||||
"All rights reserved.");
|
||||
}
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
/*
|
||||
* Print /etc/motd unless a command was specified or printing
|
||||
* it was disabled in server options or login(1) will be
|
||||
@ -604,14 +700,24 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
|
||||
*/
|
||||
if (command == NULL && options.print_motd && !quiet_login &&
|
||||
!options.use_login) {
|
||||
/* Print /etc/motd if it exists. */
|
||||
#ifdef LOGIN_CAP
|
||||
fname = login_getcapstr(lc, "welcome", NULL, NULL);
|
||||
if (fname == NULL || (f = fopen(fname, "r")) == NULL)
|
||||
f = fopen("/etc/motd", "r");
|
||||
#else /* !LOGIN_CAP */
|
||||
f = fopen("/etc/motd", "r");
|
||||
#endif /* LOGIN_CAP */
|
||||
/* Print /etc/motd if it exists. */
|
||||
if (f) {
|
||||
while (fgets(line, sizeof(line), f))
|
||||
fputs(line, stdout);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
#ifdef LOGIN_CAP
|
||||
login_close(lc);
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
/* Do common processing for the child, such as execing the command. */
|
||||
do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty);
|
||||
/* NOTREACHED */
|
||||
@ -735,15 +841,25 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
const char *display, const char *auth_proto,
|
||||
const char *auth_data, const char *ttyname)
|
||||
{
|
||||
const char *shell, *cp = NULL;
|
||||
char *shell;
|
||||
const char *cp = NULL;
|
||||
char buf[256];
|
||||
FILE *f;
|
||||
unsigned int envsize, i;
|
||||
char **env;
|
||||
char **env = NULL;
|
||||
extern char **environ;
|
||||
struct stat st;
|
||||
char *argv[10];
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
|
||||
lc = login_getpwclass(pw);
|
||||
if (lc == NULL)
|
||||
lc = login_getclassbyname(NULL, pw);
|
||||
if (pw->pw_uid != 0)
|
||||
auth_checknologin(lc);
|
||||
#else /* !LOGIN_CAP */
|
||||
f = fopen("/etc/nologin", "r");
|
||||
if (f) {
|
||||
/* /etc/nologin exists. Print its contents and exit. */
|
||||
@ -753,6 +869,11 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
if (pw->pw_uid != 0)
|
||||
exit(254);
|
||||
}
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if (options.use_login)
|
||||
#endif /* LOGIN_CAP */
|
||||
/* Set login name in the kernel. */
|
||||
if (setlogin(pw->pw_name) < 0)
|
||||
error("setlogin failed: %s", strerror(errno));
|
||||
@ -761,6 +882,42 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
/* Login(1) does this as well, and it needs uid 0 for the "-h"
|
||||
switch, so we let login(1) to this for us. */
|
||||
if (!options.use_login) {
|
||||
#ifdef LOGIN_CAP
|
||||
char **tmpenv;
|
||||
|
||||
/* Initialize temp environment */
|
||||
envsize = 64;
|
||||
env = xmalloc(envsize * sizeof(char *));
|
||||
env[0] = NULL;
|
||||
|
||||
child_set_env(&env, &envsize, "PATH",
|
||||
(pw->pw_uid == 0) ?
|
||||
_PATH_STDPATH : _PATH_DEFPATH);
|
||||
|
||||
snprintf(buf, sizeof buf, "%.200s/%.50s",
|
||||
_PATH_MAILDIR, pw->pw_name);
|
||||
child_set_env(&env, &envsize, "MAIL", buf);
|
||||
|
||||
if (getenv("TZ"))
|
||||
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
|
||||
|
||||
/* Save parent environment */
|
||||
tmpenv = environ;
|
||||
environ = env;
|
||||
|
||||
if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0)
|
||||
fatal("setusercontext failed: %s", strerror(errno));
|
||||
|
||||
/* Restore parent environment */
|
||||
env = environ;
|
||||
environ = tmpenv;
|
||||
|
||||
for (envsize = 0; env[envsize] != NULL; ++envsize)
|
||||
;
|
||||
envsize = (envsize < 100) ? 100 : envsize + 16;
|
||||
env = xrealloc(env, envsize * sizeof(char *));
|
||||
|
||||
#else /* !LOGIN_CAP */
|
||||
if (getuid() == 0 || geteuid() == 0) {
|
||||
if (setgid(pw->pw_gid) < 0) {
|
||||
perror("setgid");
|
||||
@ -778,12 +935,16 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
}
|
||||
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
|
||||
fatal("Failed to set uids to %d.", (int) pw->pw_uid);
|
||||
#endif /* LOGIN_CAP */
|
||||
}
|
||||
/*
|
||||
* Get the shell from the password data. An empty shell field is
|
||||
* legal, and means /bin/sh.
|
||||
*/
|
||||
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
|
||||
#ifdef LOGIN_CAP
|
||||
shell = login_getcapstr(lc, "shell", shell, shell);
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
#ifdef AFS
|
||||
/* Try to get AFS tokens for the local cell. */
|
||||
@ -798,24 +959,31 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
#endif /* AFS */
|
||||
|
||||
/* Initialize the environment. */
|
||||
envsize = 100;
|
||||
env = xmalloc(envsize * sizeof(char *));
|
||||
env[0] = NULL;
|
||||
if (env == NULL) {
|
||||
envsize = 100;
|
||||
env = xmalloc(envsize * sizeof(char *));
|
||||
env[0] = NULL;
|
||||
}
|
||||
|
||||
if (!options.use_login) {
|
||||
/* Set basic environment. */
|
||||
child_set_env(&env, &envsize, "USER", pw->pw_name);
|
||||
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
|
||||
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
|
||||
#ifndef LOGIN_CAP
|
||||
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
|
||||
|
||||
snprintf(buf, sizeof buf, "%.200s/%.50s",
|
||||
_PATH_MAILDIR, pw->pw_name);
|
||||
child_set_env(&env, &envsize, "MAIL", buf);
|
||||
#endif /* !LOGIN_CAP */
|
||||
|
||||
/* Normal systems set SHELL by default. */
|
||||
child_set_env(&env, &envsize, "SHELL", shell);
|
||||
}
|
||||
#ifdef LOGIN_CAP
|
||||
if (options.use_login)
|
||||
#endif /* LOGIN_CAP */
|
||||
if (getenv("TZ"))
|
||||
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
|
||||
|
||||
@ -853,6 +1021,31 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
child_set_env(&env, &envsize, "KRBTKFILE", ticket);
|
||||
}
|
||||
#endif /* KRB4 */
|
||||
#ifdef KRB5
|
||||
{
|
||||
extern krb5_ccache mem_ccache;
|
||||
|
||||
if (mem_ccache) {
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache;
|
||||
#ifdef AFS
|
||||
if (k_hasafs())
|
||||
krb5_afslog(ssh_context, mem_ccache, NULL, NULL);
|
||||
#endif /* AFS */
|
||||
|
||||
problem = krb5_cc_default(ssh_context, &ccache);
|
||||
if (problem) {}
|
||||
else {
|
||||
problem = krb5_cc_copy_cache(ssh_context, mem_ccache, ccache);
|
||||
if (problem) {}
|
||||
}
|
||||
|
||||
krb5_cc_close(ssh_context, ccache);
|
||||
}
|
||||
|
||||
krb5_cleanup_proc(NULL);
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
|
||||
if (xauthfile)
|
||||
child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
|
||||
@ -903,13 +1096,50 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
* initgroups, because at least on Solaris 2.3 it leaves file
|
||||
* descriptors open.
|
||||
*/
|
||||
for (i = 3; i < 64; i++)
|
||||
for (i = 3; i < getdtablesize(); i++)
|
||||
close(i);
|
||||
|
||||
/* Change current directory to the user\'s home directory. */
|
||||
if (chdir(pw->pw_dir) < 0)
|
||||
if (
|
||||
#ifdef __FreeBSD__
|
||||
!*pw->pw_dir ||
|
||||
#endif /* __FreeBSD__ */
|
||||
chdir(pw->pw_dir) < 0
|
||||
) {
|
||||
#ifdef __FreeBSD__
|
||||
int quiet_login = 0;
|
||||
#endif /* __FreeBSD__ */
|
||||
#ifdef LOGIN_CAP
|
||||
if (login_getcapbool(lc, "requirehome", 0)) {
|
||||
(void)printf("Home directory not available\n");
|
||||
log("LOGIN %.200s REFUSED (HOMEDIR) ON TTY %.200s",
|
||||
pw->pw_name, ttyname);
|
||||
exit(254);
|
||||
}
|
||||
#endif /* LOGIN_CAP */
|
||||
#ifdef __FreeBSD__
|
||||
if (chdir("/") < 0) {
|
||||
(void)printf("Cannot find root directory\n");
|
||||
log("LOGIN %.200s REFUSED (ROOTDIR) ON TTY %.200s",
|
||||
pw->pw_name, ttyname);
|
||||
exit(254);
|
||||
}
|
||||
#ifdef LOGIN_CAP
|
||||
quiet_login = login_getcapbool(lc, "hushlogin", 0);
|
||||
#endif /* LOGIN_CAP */
|
||||
if (!quiet_login || *pw->pw_dir)
|
||||
(void)printf(
|
||||
"No home directory.\nLogging in with home = \"/\".\n");
|
||||
|
||||
#else /* !__FreeBSD__ */
|
||||
|
||||
fprintf(stderr, "Could not chdir to home directory %s: %s\n",
|
||||
pw->pw_dir, strerror(errno));
|
||||
#endif /* __FreeBSD__ */
|
||||
}
|
||||
#ifdef LOGIN_CAP
|
||||
login_close(lc);
|
||||
#endif /* LOGIN_CAP */
|
||||
|
||||
/*
|
||||
* Must take new environment into use so that .ssh/rc, /etc/sshrc and
|
||||
@ -989,7 +1219,11 @@ do_child(const char *command, struct passwd * pw, const char *term,
|
||||
mailbox = getenv("MAIL");
|
||||
if (mailbox != NULL) {
|
||||
if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0)
|
||||
#ifdef __FreeBSD__
|
||||
;
|
||||
#else /* !__FreeBSD__ */
|
||||
printf("No mail.\n");
|
||||
#endif /* __FreeBSD__ */
|
||||
else if (mailstat.st_mtime < mailstat.st_atime)
|
||||
printf("You have mail.\n");
|
||||
else
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* $OpenBSD: ssh-agent.c,v 1.26 2000/03/16 20:56:14 markus Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
/* $OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -6,12 +7,10 @@
|
||||
* All rights reserved
|
||||
* Created: Wed Mar 29 03:46:59 1995 ylo
|
||||
* The authentication agent program.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: ssh-agent.c,v 1.26 2000/03/16 20:56:14 markus Exp $");
|
||||
RCSID("$OpenBSD: ssh-agent.c,v 1.31 2000/04/29 18:11:52 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "rsa.h"
|
||||
@ -48,7 +47,7 @@ Identity *identities = NULL;
|
||||
int max_fd = 0;
|
||||
|
||||
/* pid of shell == parent of agent */
|
||||
int parent_pid = -1;
|
||||
pid_t parent_pid = -1;
|
||||
|
||||
/* pathname and directory for AUTH_SOCKET */
|
||||
char socket_name[1024];
|
||||
@ -176,7 +175,7 @@ process_remove_identity(SocketEntry *e)
|
||||
buffer_get_bignum(&e->input, n);
|
||||
|
||||
if (bits != BN_num_bits(n))
|
||||
error("Warning: identity keysize mismatch: actual %d, announced %d",
|
||||
log("Warning: identity keysize mismatch: actual %d, announced %d",
|
||||
BN_num_bits(n), bits);
|
||||
|
||||
/* Check if we have the key. */
|
||||
@ -405,7 +404,7 @@ prepare_select(fd_set *readset, fd_set *writeset)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
after_select(fd_set *readset, fd_set *writeset)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -438,6 +437,8 @@ after_select(fd_set *readset, fd_set *writeset)
|
||||
shutdown(sockets[i].fd, SHUT_RDWR);
|
||||
close(sockets[i].fd);
|
||||
sockets[i].type = AUTH_UNUSED;
|
||||
buffer_free(&sockets[i].input);
|
||||
buffer_free(&sockets[i].output);
|
||||
break;
|
||||
}
|
||||
buffer_consume(&sockets[i].output, len);
|
||||
@ -448,6 +449,8 @@ after_select(fd_set *readset, fd_set *writeset)
|
||||
shutdown(sockets[i].fd, SHUT_RDWR);
|
||||
close(sockets[i].fd);
|
||||
sockets[i].type = AUTH_UNUSED;
|
||||
buffer_free(&sockets[i].input);
|
||||
buffer_free(&sockets[i].output);
|
||||
break;
|
||||
}
|
||||
buffer_append(&sockets[i].input, buf, len);
|
||||
@ -462,7 +465,7 @@ after_select(fd_set *readset, fd_set *writeset)
|
||||
void
|
||||
check_parent_exists(int sig)
|
||||
{
|
||||
if (kill(parent_pid, 0) < 0) {
|
||||
if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
|
||||
/* printf("Parent has died - Authentication agent exiting.\n"); */
|
||||
exit(1);
|
||||
}
|
||||
@ -548,6 +551,7 @@ main(int ac, char **av)
|
||||
}
|
||||
pid = atoi(pidstr);
|
||||
if (pid < 1) { /* XXX PID_MAX check too */
|
||||
/* Yes, PID_MAX check please */
|
||||
fprintf(stderr, "%s=\"%s\", which is not a good PID\n",
|
||||
SSH_AGENTPID_ENV_NAME, pidstr);
|
||||
exit(1);
|
||||
@ -639,8 +643,8 @@ main(int ac, char **av)
|
||||
}
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGHUP, cleanup_exit);
|
||||
signal(SIGTERM, cleanup_exit);
|
||||
signal(SIGHUP, cleanup_exit);
|
||||
signal(SIGTERM, cleanup_exit);
|
||||
while (1) {
|
||||
FD_ZERO(&readset);
|
||||
FD_ZERO(&writeset);
|
||||
|
@ -10,6 +10,7 @@
|
||||
.\" Created: Sat Apr 22 21:55:14 1995 ylo
|
||||
.\"
|
||||
.\" $Id: ssh.1,v 1.43 2000/03/24 03:04:46 brad Exp $
|
||||
.\" $Id: ssh.1,v 1.52 2000/05/08 17:21:32 hugh Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 25, 1999
|
||||
@ -25,8 +26,8 @@
|
||||
.Op Ar command
|
||||
.Pp
|
||||
.Nm ssh
|
||||
.Op Fl afgknqtvxCPX46
|
||||
.Op Fl c Ar blowfish | 3des
|
||||
.Op Fl afgknqtvxCPX246
|
||||
.Op Fl c Ar cipher_spec
|
||||
.Op Fl e Ar escape_char
|
||||
.Op Fl i Ar identity_file
|
||||
.Op Fl l Ar login_name
|
||||
@ -64,7 +65,10 @@ arbitrary TCP/IP ports can also be forwarded over the secure channel.
|
||||
connects and logs into the specified
|
||||
.Ar hostname .
|
||||
The user must prove
|
||||
his/her identity to the remote machine using one of several methods.
|
||||
his/her identity to the remote machine using one of several methods
|
||||
depending on the protocol version used:
|
||||
.Pp
|
||||
.Ss SSH protocol version 1
|
||||
.Pp
|
||||
First, if the machine the user logs in from is listed in
|
||||
.Pa /etc/hosts.equiv
|
||||
@ -89,8 +93,8 @@ or
|
||||
.Pa hosts.equiv
|
||||
method combined with RSA-based host authentication.
|
||||
It means that if the login would be permitted by
|
||||
.Pa \&.rhosts ,
|
||||
.Pa \&.shosts ,
|
||||
.Pa $HOME/.rhosts ,
|
||||
.Pa $HOME/.shosts ,
|
||||
.Pa /etc/hosts.equiv ,
|
||||
or
|
||||
.Pa /etc/ssh/shosts.equiv ,
|
||||
@ -106,7 +110,7 @@ This authentication method closes security holes due to IP
|
||||
spoofing, DNS spoofing and routing spoofing.
|
||||
[Note to the administrator:
|
||||
.Pa /etc/hosts.equiv ,
|
||||
.Pa \&.rhosts ,
|
||||
.Pa $HOME/.rhosts ,
|
||||
and the rlogin/rsh protocol in general, are inherently insecure and should be
|
||||
disabled if security is desired.]
|
||||
.Pp
|
||||
@ -117,10 +121,10 @@ The scheme is based on public-key cryptography: there are cryptosystems
|
||||
where encryption and decryption are done using separate keys, and it
|
||||
is not possible to derive the decryption key from the encryption key.
|
||||
RSA is one such system.
|
||||
The idea is that each user creates a public/private
|
||||
The idea is that each user creates a public/private
|
||||
key pair for authentication purposes.
|
||||
The server knows the public key, and only the user knows the private key.
|
||||
The file
|
||||
The file
|
||||
.Pa $HOME/.ssh/authorized_keys
|
||||
lists the public keys that are permitted for logging
|
||||
in.
|
||||
@ -144,18 +148,18 @@ implements the RSA authentication protocol automatically.
|
||||
The user creates his/her RSA key pair by running
|
||||
.Xr ssh-keygen 1 .
|
||||
This stores the private key in
|
||||
.Pa \&.ssh/identity
|
||||
.Pa $HOME/.ssh/identity
|
||||
and the public key in
|
||||
.Pa \&.ssh/identity.pub
|
||||
.Pa $HOME/.ssh/identity.pub
|
||||
in the user's home directory.
|
||||
The user should then copy the
|
||||
.Pa identity.pub
|
||||
to
|
||||
.Pa \&.ssh/authorized_keys
|
||||
.Pa $HOME/.ssh/authorized_keys
|
||||
in his/her home directory on the remote machine (the
|
||||
.Pa authorized_keys
|
||||
file corresponds to the conventional
|
||||
.Pa \&.rhosts
|
||||
.Pa $HOME/.rhosts
|
||||
file, and has one key
|
||||
per line, though the lines can be very long).
|
||||
After this, the user can log in without giving the password.
|
||||
@ -175,6 +179,38 @@ The password is sent to the remote
|
||||
host for checking; however, since all communications are encrypted,
|
||||
the password cannot be seen by someone listening on the network.
|
||||
.Pp
|
||||
.Ss SSH protocol version 2
|
||||
.Pp
|
||||
When a user connects using the protocol version 2
|
||||
different authentication methods are available:
|
||||
At first, the client attempts to authenticate using the public key method.
|
||||
If this method fails password authentication is tried.
|
||||
.Pp
|
||||
The public key method is similar to RSA authentication described
|
||||
in the previous section except that the DSA algorithm is used
|
||||
instead of the patented RSA algorithm.
|
||||
The client uses his private DSA key
|
||||
.Pa $HOME/.ssh/id_dsa
|
||||
to sign the session identifier and sends the result to the server.
|
||||
The server checks whether the matching public key is listed in
|
||||
.Pa $HOME/.ssh/authorized_keys2
|
||||
and grants access if both the key is found and the signature is correct.
|
||||
The session identifier is derived from a shared Diffie-Hellman value
|
||||
and is only known to the client and the server.
|
||||
.Pp
|
||||
If public key authentication fails or is not available a password
|
||||
can be sent encrypted to the remote host for proving the user's identity.
|
||||
This protocol 2 implementation does not yet support Kerberos or
|
||||
S/Key authentication.
|
||||
.Pp
|
||||
Protocol 2 provides additional mechanisms for confidentiality
|
||||
(the traffic is encrypted using 3DES, Blowfish, CAST128 or Arcfour)
|
||||
and integrity (hmac-sha1, hmac-md5).
|
||||
Note that protocol 1 lacks a strong mechanism for ensuring the
|
||||
integrity of the connection.
|
||||
.Pp
|
||||
.Ss Login session and remote execution
|
||||
.Pp
|
||||
When the user's identity has been accepted by the server, the server
|
||||
either executes the given command, or logs into the machine and gives
|
||||
the user a normal shell on the remote machine.
|
||||
@ -220,6 +256,8 @@ The exit status of the remote program is returned as the exit status
|
||||
of
|
||||
.Nm ssh .
|
||||
.Pp
|
||||
.Ss X11 and TCP forwarding
|
||||
.Pp
|
||||
If the user is using X11 (the
|
||||
.Ev DISPLAY
|
||||
environment variable is set), the connection to the X11 display can
|
||||
@ -264,15 +302,22 @@ be specified either on command line or in a configuration file.
|
||||
One possible application of TCP/IP forwarding is a secure connection to an
|
||||
electronic purse; another is going trough firewalls.
|
||||
.Pp
|
||||
.Ss Server authentication
|
||||
.Pp
|
||||
.Nm
|
||||
automatically maintains and checks a database containing RSA-based
|
||||
automatically maintains and checks a database containing
|
||||
identifications for all hosts it has ever been used with.
|
||||
The database is stored in
|
||||
.Pa \&.ssh/known_hosts
|
||||
RSA host keys are stored in
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
and
|
||||
DSA host keys are stored in
|
||||
.Pa $HOME/.ssh/known_hosts2
|
||||
in the user's home directory.
|
||||
Additionally, the file
|
||||
Additionally, the files
|
||||
.Pa /etc/ssh/ssh_known_hosts
|
||||
is automatically checked for known hosts.
|
||||
and
|
||||
.Pa /etc/ssh/ssh_known_hosts2
|
||||
are automatically checked for known hosts.
|
||||
Any new hosts are automatically added to the user's file.
|
||||
If a host's identification
|
||||
ever changes,
|
||||
@ -295,15 +340,20 @@ This may also be specified on a per-host basis in the configuration file.
|
||||
Selects the cipher to use for encrypting the session.
|
||||
.Ar 3des
|
||||
is used by default.
|
||||
It is believed to be secure.
|
||||
It is believed to be secure.
|
||||
.Ar 3des
|
||||
(triple-des) is an encrypt-decrypt-encrypt triple with three different keys.
|
||||
It is presumably more secure than the
|
||||
.Ar des
|
||||
cipher which is no longer supported in ssh.
|
||||
cipher which is no longer supported in
|
||||
.Nm ssh .
|
||||
.Ar blowfish
|
||||
is a fast block cipher, it appears very secure and is much faster than
|
||||
.Ar 3des .
|
||||
.It Fl c Ar "3des-cbc,blowfish-cbc,arcfour,cast128-cbc"
|
||||
Additionally, for protocol version 2 a comma-separated list of ciphers can
|
||||
be specified in order of preference. Protocol version 2 supports
|
||||
3DES, Blowfish and CAST128 in CBC mode and Arcfour.
|
||||
.It Fl e Ar ch|^ch|none
|
||||
Sets the escape character for sessions with a pty (default:
|
||||
.Ql ~ ) .
|
||||
@ -324,7 +374,7 @@ This is useful if
|
||||
.Nm
|
||||
is going to ask for passwords or passphrases, but the user
|
||||
wants it in the background.
|
||||
This implies
|
||||
This implies
|
||||
.Fl n .
|
||||
The recommended way to start X11 programs at a remote site is with
|
||||
something like
|
||||
@ -332,10 +382,10 @@ something like
|
||||
.It Fl g
|
||||
Allows remote hosts to connect to local forwarded ports.
|
||||
.It Fl i Ar identity_file
|
||||
Selects the file from which the identity (private key) for
|
||||
Selects the file from which the identity (private key) for
|
||||
RSA authentication is read.
|
||||
Default is
|
||||
.Pa \&.ssh/identity
|
||||
Default is
|
||||
.Pa $HOME/.ssh/identity
|
||||
in the user's home directory.
|
||||
Identity files may also be specified on
|
||||
a per-host basis in the configuration file.
|
||||
@ -457,6 +507,10 @@ from the local machine.
|
||||
Port forwardings can also be specified in the configuration file.
|
||||
Privileged ports can be forwarded only when
|
||||
logging in as root on the remote machine.
|
||||
.It Fl 2
|
||||
Forces
|
||||
.Nm
|
||||
to try protocol version 2 only.
|
||||
.It Fl 4
|
||||
Forces
|
||||
.Nm
|
||||
@ -550,6 +604,12 @@ and
|
||||
are supported.
|
||||
The default is
|
||||
.Dq 3des .
|
||||
.It Cm Ciphers
|
||||
Specifies the ciphers allowed for protocol version 2
|
||||
in order of preference.
|
||||
Multiple ciphers must be comma-separated.
|
||||
The default is
|
||||
.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc .
|
||||
.It Cm Compression
|
||||
Specifies whether to use compression.
|
||||
The argument must be
|
||||
@ -567,6 +627,15 @@ Specifies the number of tries (one per second) to make before falling
|
||||
back to rsh or exiting.
|
||||
The argument must be an integer.
|
||||
This may be useful in scripts if the connection sometimes fails.
|
||||
.It Cm DSAAuthentication
|
||||
Specifies whether to try DSA authentication.
|
||||
The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
DSA authentication will only be
|
||||
attempted if a DSA identity file exists.
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm EscapeChar
|
||||
Sets the escape character (default:
|
||||
.Ql ~ ) .
|
||||
@ -604,7 +673,7 @@ Specifies whether X11 connections will be automatically redirected
|
||||
over the secure channel and
|
||||
.Ev DISPLAY
|
||||
set.
|
||||
The argument must be
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
@ -632,7 +701,7 @@ specifications).
|
||||
.It Cm IdentityFile
|
||||
Specifies the file from which the user's RSA authentication identity
|
||||
is read (default
|
||||
.Pa .ssh/identity
|
||||
.Pa $HOME/.ssh/identity
|
||||
in the user's home directory).
|
||||
Additionally, any identities represented by the authentication agent
|
||||
will be used for authentication.
|
||||
@ -641,6 +710,16 @@ syntax to refer to a user's home directory.
|
||||
It is possible to have
|
||||
multiple identity files specified in configuration files; all these
|
||||
identities will be tried in sequence.
|
||||
.It Cm IdentityFile2
|
||||
Specifies the file from which the user's DSA authentication identity
|
||||
is read (default
|
||||
.Pa $HOME/.ssh/id_dsa
|
||||
in the user's home directory).
|
||||
The file name may use the tilde
|
||||
syntax to refer to a user's home directory.
|
||||
It is possible to have
|
||||
multiple identity files specified in configuration files; all these
|
||||
identities will be tried in sequence.
|
||||
.It Cm KeepAlive
|
||||
Specifies whether the system should send keepalive messages to the
|
||||
other side.
|
||||
@ -696,9 +775,25 @@ The argument to this keyword must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
Note that this option applies to both protocol version 1 and 2.
|
||||
.It Cm Port
|
||||
Specifies the port number to connect on the remote host.
|
||||
Default is 22.
|
||||
.It Cm Protocol
|
||||
Specifies the protocol versions
|
||||
.Nm
|
||||
should support in order of preference.
|
||||
The possible values are
|
||||
.Dq 1
|
||||
and
|
||||
.Dq 2 .
|
||||
Multiple versions must be comma-separated.
|
||||
The default is
|
||||
.Dq 1,2 .
|
||||
This means that
|
||||
.Nm
|
||||
tries version 1 and falls back to version 2
|
||||
if version 1 is not available.
|
||||
.It Cm ProxyCommand
|
||||
Specifies the command to use to connect to the server.
|
||||
The command
|
||||
@ -763,6 +858,7 @@ or
|
||||
RSA authentication will only be
|
||||
attempted if the identity file exists, or an authentication agent is
|
||||
running.
|
||||
Note that this option applies to protocol version 1 only.
|
||||
.It Cm SkeyAuthentication
|
||||
Specifies whether to use
|
||||
.Xr skey 1
|
||||
@ -779,10 +875,14 @@ If this flag is set to
|
||||
.Nm
|
||||
ssh will never automatically add host keys to the
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
file, and refuses to connect hosts whose host key has changed.
|
||||
and
|
||||
.Pa $HOME/.ssh/known_hosts2
|
||||
files, and refuses to connect hosts whose host key has changed.
|
||||
This provides maximum protection against trojan horse attacks.
|
||||
However, it can be somewhat annoying if you don't have good
|
||||
.Pa /etc/ssh/ssh_known_hosts
|
||||
and
|
||||
.Pa /etc/ssh/ssh_known_hosts2
|
||||
files installed and frequently
|
||||
connect new hosts.
|
||||
Basically this option forces the user to manually
|
||||
@ -841,7 +941,7 @@ will normally set the following environment variables:
|
||||
The
|
||||
.Ev DISPLAY
|
||||
variable indicates the location of the X11 server.
|
||||
It is automatically set by
|
||||
It is automatically set by
|
||||
.Nm
|
||||
to point to a value of the form
|
||||
.Dq hostname:n
|
||||
@ -902,28 +1002,36 @@ in
|
||||
.Pa /etc/ssh/ssh_known_hosts ) .
|
||||
See
|
||||
.Xr sshd 8 .
|
||||
.It Pa $HOME/.ssh/identity
|
||||
Contains the RSA authentication identity of the user.
|
||||
This file
|
||||
contains sensitive data and should be readable by the user but not
|
||||
.It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa
|
||||
Contains the RSA and the DSA authentication identity of the user.
|
||||
These files
|
||||
contain sensitive data and should be readable by the user but not
|
||||
accessible by others (read/write/execute).
|
||||
Note that
|
||||
.Nm
|
||||
ignores this file if it is accessible by others.
|
||||
ignores a private key file if it is accessible by others.
|
||||
It is possible to specify a passphrase when
|
||||
generating the key; the passphrase will be used to encrypt the
|
||||
sensitive part of this file using 3DES.
|
||||
.It Pa $HOME/.ssh/identity.pub
|
||||
.It Pa $HOME/.ssh/identity.pub, $HOME/.ssh/id_dsa.pub
|
||||
Contains the public key for authentication (public part of the
|
||||
identity file in human-readable form).
|
||||
The contents of this file should be added to
|
||||
The contents of the
|
||||
.Pa $HOME/.ssh/identity.pub
|
||||
file should be added to
|
||||
.Pa $HOME/.ssh/authorized_keys
|
||||
on all machines
|
||||
where you wish to log in using RSA authentication.
|
||||
This file is not
|
||||
The contents of the
|
||||
.Pa $HOME/.ssh/id_dsa.pub
|
||||
file should be added to
|
||||
.Pa $HOME/.ssh/authorized_keys2
|
||||
on all machines
|
||||
where you wish to log in using DSA authentication.
|
||||
These files are not
|
||||
sensitive and can (but need not) be readable by anyone.
|
||||
This file is
|
||||
never used automatically and is not necessary; it is only provided for
|
||||
These files are
|
||||
never used automatically and are not necessary; they is only provided for
|
||||
the convenience of the user.
|
||||
.It Pa $HOME/.ssh/config
|
||||
This is the per-user configuration file.
|
||||
@ -945,9 +1053,17 @@ modulus, public exponent, modulus, and comment fields, separated by
|
||||
spaces).
|
||||
This file is not highly sensitive, but the recommended
|
||||
permissions are read/write for the user, and not accessible by others.
|
||||
.It Pa /etc/ssh/ssh_known_hosts
|
||||
.It Pa $HOME/.ssh/authorized_keys2
|
||||
Lists the DSA keys that can be used for logging in as this user.
|
||||
This file is not highly sensitive, but the recommended
|
||||
permissions are read/write for the user, and not accessible by others.
|
||||
.It Pa /etc/ssh/ssh_known_hosts, /etc/ssh/ssh_known_hosts2
|
||||
Systemwide list of known host keys.
|
||||
This file should be prepared by the
|
||||
.Pa /etc/ssh_known_hosts
|
||||
contains RSA and
|
||||
.Pa /etc/ssh_known_hosts2
|
||||
contains DSA keys.
|
||||
These files should be prepared by the
|
||||
system administrator to contain the public host keys of all machines in the
|
||||
organization.
|
||||
This file should be world-readable.
|
||||
@ -1006,7 +1122,7 @@ you can store it in
|
||||
.Pa $HOME/.ssh/known_hosts .
|
||||
The easiest way to do this is to
|
||||
connect back to the client from the server machine using ssh; this
|
||||
will automatically add the host key inxi
|
||||
will automatically add the host key to
|
||||
.Pa $HOME/.ssh/known_hosts .
|
||||
.It Pa $HOME/.shosts
|
||||
This file is used exactly the same way as
|
||||
@ -1034,7 +1150,7 @@ Additionally, successful RSA host authentication is normally
|
||||
required.
|
||||
This file should only be writable by root.
|
||||
.It Pa /etc/ssh/shosts.equiv
|
||||
This file is processed exactly as
|
||||
This file is processed exactly as
|
||||
.Pa /etc/hosts.equiv .
|
||||
This file may be useful to permit logins using
|
||||
.Nm
|
||||
@ -1068,6 +1184,7 @@ but with bugs removed and newer features re-added.
|
||||
Rapidly after the
|
||||
1.2.12 release, newer versions of the original ssh bore successively
|
||||
more restrictive licenses, and thus demand for a free version was born.
|
||||
.Pp
|
||||
This version of OpenSSH
|
||||
.Bl -bullet
|
||||
.It
|
||||
@ -1077,8 +1194,8 @@ directly removed from the source code; any licensed or patented components
|
||||
are chosen from
|
||||
external libraries.
|
||||
.It
|
||||
has been updated to support ssh protocol 1.5, making it compatible with
|
||||
all other ssh protocol 1 clients and servers.
|
||||
has been updated to support SSH protocol 1.5 and 2, making it compatible with
|
||||
all other SSH clients and servers.
|
||||
.It
|
||||
contains added support for
|
||||
.Xr kerberos 8
|
||||
@ -1094,6 +1211,8 @@ are required for proper operation.
|
||||
.Pp
|
||||
OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl,
|
||||
Niels Provos, Theo de Raadt, and Dug Song.
|
||||
.Pp
|
||||
The support for SSH protocol 2 was written by Markus Friedl.
|
||||
.Sh SEE ALSO
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1 ,
|
||||
|
@ -13,7 +13,11 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: ssh.c,v 1.43 2000/03/23 21:52:02 markus Exp $");
|
||||
RCSID("$Id: ssh.c,v 1.51 2000/05/08 17:12:15 markus Exp $");
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
@ -23,6 +27,14 @@ RCSID("$Id: ssh.c,v 1.43 2000/03/23 21:52:02 markus Exp $");
|
||||
#include "readconf.h"
|
||||
#include "uidswap.h"
|
||||
|
||||
#include "ssh2.h"
|
||||
#include "compat.h"
|
||||
#include "channels.h"
|
||||
#include "key.h"
|
||||
#include "authfile.h"
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
|
||||
Default value is AF_UNSPEC means both IPv4 and IPv6. */
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
@ -30,8 +42,13 @@ int IPv4or6 = AF_UNSPEC;
|
||||
/* Flag indicating whether debug mode is on. This can be set on the command line. */
|
||||
int debug_flag = 0;
|
||||
|
||||
/* Flag indicating whether a tty should be allocated */
|
||||
int tty_flag = 0;
|
||||
|
||||
/* don't exec a shell */
|
||||
int no_shell_flag = 0;
|
||||
int no_tty_flag = 0;
|
||||
|
||||
/*
|
||||
* Flag indicating that nothing should be read from stdin. This can be set
|
||||
* on the command line.
|
||||
@ -81,6 +98,9 @@ RSA *host_private_key = NULL;
|
||||
/* Original real UID. */
|
||||
uid_t original_real_uid;
|
||||
|
||||
/* command to be executed */
|
||||
Buffer command;
|
||||
|
||||
/* Prints a help message to the user. This function never returns. */
|
||||
|
||||
void
|
||||
@ -98,6 +118,7 @@ usage()
|
||||
fprintf(stderr, " -X Enable X11 connection forwarding.\n");
|
||||
fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n");
|
||||
fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n");
|
||||
fprintf(stderr, " -T Do not allocate a tty.\n");
|
||||
fprintf(stderr, " -v Verbose; display verbose debugging messages.\n");
|
||||
fprintf(stderr, " -V Display version number only.\n");
|
||||
fprintf(stderr, " -P Don't allocate a privileged port.\n");
|
||||
@ -114,9 +135,11 @@ usage()
|
||||
fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0);
|
||||
fprintf(stderr, " forward them to the other side by connecting to host:port.\n");
|
||||
fprintf(stderr, " -C Enable compression.\n");
|
||||
fprintf(stderr, " -N Do not execute a shell or command.\n");
|
||||
fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n");
|
||||
fprintf(stderr, " -4 Use IPv4 only.\n");
|
||||
fprintf(stderr, " -6 Use IPv6 only.\n");
|
||||
fprintf(stderr, " -2 Force protocol version 2.\n");
|
||||
fprintf(stderr, " -o 'option' Process the option as if it was read from a configuration file.\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -162,23 +185,22 @@ rsh_connect(char *host, char *user, Buffer * command)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ssh_session(void);
|
||||
int ssh_session2(void);
|
||||
|
||||
/*
|
||||
* Main program for the ssh client.
|
||||
*/
|
||||
int
|
||||
main(int ac, char **av)
|
||||
{
|
||||
int i, opt, optind, type, exit_status, ok, authfd;
|
||||
int i, opt, optind, exit_status, ok;
|
||||
u_short fwd_port, fwd_host_port;
|
||||
char *optarg, *cp, buf[256];
|
||||
Buffer command;
|
||||
struct winsize ws;
|
||||
struct stat st;
|
||||
struct passwd *pw, pwcopy;
|
||||
int interactive = 0, dummy;
|
||||
int have_pty = 0;
|
||||
int dummy;
|
||||
uid_t original_effective_uid;
|
||||
int plen;
|
||||
|
||||
/*
|
||||
* Save the original real uid. It will be needed later (uid-swapping
|
||||
@ -234,8 +256,8 @@ main(int ac, char **av)
|
||||
if (host)
|
||||
break;
|
||||
if ((cp = strchr(av[optind], '@'))) {
|
||||
if(cp == av[optind])
|
||||
usage();
|
||||
if(cp == av[optind])
|
||||
usage();
|
||||
options.user = av[optind];
|
||||
*cp = '\0';
|
||||
host = ++cp;
|
||||
@ -259,39 +281,34 @@ main(int ac, char **av)
|
||||
optarg = NULL;
|
||||
}
|
||||
switch (opt) {
|
||||
case '2':
|
||||
options.protocol = SSH_PROTO_2;
|
||||
break;
|
||||
case '4':
|
||||
IPv4or6 = AF_INET;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
IPv4or6 = AF_INET6;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
stdin_null_flag = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
fork_after_authentication_flag = 1;
|
||||
stdin_null_flag = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
options.forward_x11 = 0;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
options.forward_x11 = 1;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
options.gateway_ports = 1;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
options.use_privileged_port = 0;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
options.forward_agent = 0;
|
||||
break;
|
||||
@ -314,26 +331,24 @@ main(int ac, char **av)
|
||||
options.identity_files[options.num_identity_files++] =
|
||||
xstrdup(optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
tty_flag = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
|
||||
SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
|
||||
fprintf(stderr, "Compiled with SSL.\n");
|
||||
fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n",
|
||||
SSH_VERSION,
|
||||
PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
|
||||
PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
|
||||
fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay());
|
||||
if (opt == 'V')
|
||||
exit(0);
|
||||
debug_flag = 1;
|
||||
options.log_level = SYSLOG_LEVEL_DEBUG;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
options.log_level = SYSLOG_LEVEL_QUIET;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
if (optarg[0] == '^' && optarg[2] == 0 &&
|
||||
(unsigned char) optarg[1] >= 64 && (unsigned char) optarg[1] < 128)
|
||||
@ -347,23 +362,26 @@ main(int ac, char **av)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
options.cipher = cipher_number(optarg);
|
||||
if (options.cipher == -1) {
|
||||
fprintf(stderr, "Unknown cipher type '%s'\n", optarg);
|
||||
exit(1);
|
||||
if (ciphers_valid(optarg)) {
|
||||
/* SSH2 only */
|
||||
options.ciphers = xstrdup(optarg);
|
||||
options.cipher = SSH_CIPHER_ILLEGAL;
|
||||
} else {
|
||||
/* SSH1 only */
|
||||
options.cipher = cipher_number(optarg);
|
||||
if (options.cipher == -1) {
|
||||
fprintf(stderr, "Unknown cipher type '%s'\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
options.port = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
options.user = optarg;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf,
|
||||
&fwd_host_port) != 3 &&
|
||||
@ -375,7 +393,6 @@ main(int ac, char **av)
|
||||
}
|
||||
add_remote_forward(&options, fwd_port, buf, fwd_host_port);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf,
|
||||
&fwd_host_port) != 3 &&
|
||||
@ -387,18 +404,22 @@ main(int ac, char **av)
|
||||
}
|
||||
add_local_forward(&options, fwd_port, buf, fwd_host_port);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
options.compression = 1;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
no_shell_flag = 1;
|
||||
no_tty_flag = 1;
|
||||
break;
|
||||
case 'T':
|
||||
no_tty_flag = 1;
|
||||
break;
|
||||
case 'o':
|
||||
dummy = 1;
|
||||
if (process_config_line(&options, host ? host : "", optarg,
|
||||
"command-line", 0, &dummy) != 0)
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
@ -408,15 +429,8 @@ main(int ac, char **av)
|
||||
if (!host)
|
||||
usage();
|
||||
|
||||
/* check if RSA support exists */
|
||||
if (rsa_alive() == 0) {
|
||||
extern char *__progname;
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
}
|
||||
/* Initialize the command to execute on remote host. */
|
||||
buffer_init(&command);
|
||||
|
||||
@ -452,6 +466,10 @@ main(int ac, char **av)
|
||||
fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
|
||||
tty_flag = 0;
|
||||
}
|
||||
/* force */
|
||||
if (no_tty_flag)
|
||||
tty_flag = 0;
|
||||
|
||||
/* Get user data. */
|
||||
pw = getpwuid(original_real_uid);
|
||||
if (!pw) {
|
||||
@ -485,6 +503,20 @@ main(int ac, char **av)
|
||||
/* reinit */
|
||||
log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0);
|
||||
|
||||
/* check if RSA support exists */
|
||||
if ((options.protocol & SSH_PROTO_1) &&
|
||||
rsa_alive() == 0) {
|
||||
log("%s: no RSA support in libssl and libcrypto. See ssl(8).",
|
||||
__progname);
|
||||
log("Disabling protocol version 1");
|
||||
options.protocol &= ~ (SSH_PROTO_1|SSH_PROTO_1_PREFERRED);
|
||||
}
|
||||
if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) {
|
||||
fprintf(stderr, "%s: No protocol version available.\n",
|
||||
__progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options.user == NULL)
|
||||
options.user = xstrdup(pw->pw_name);
|
||||
|
||||
@ -551,9 +583,12 @@ main(int ac, char **av)
|
||||
* authentication. This must be done before releasing extra
|
||||
* privileges, because the file is only readable by root.
|
||||
*/
|
||||
if (ok) {
|
||||
if (ok && (options.protocol & SSH_PROTO_1)) {
|
||||
Key k;
|
||||
host_private_key = RSA_new();
|
||||
if (load_private_key(HOST_KEY_FILE, "", host_private_key, NULL))
|
||||
k.type = KEY_RSA;
|
||||
k.rsa = host_private_key;
|
||||
if (load_private_key(HOST_KEY_FILE, "", &k, NULL))
|
||||
host_private_key_loaded = 1;
|
||||
}
|
||||
/*
|
||||
@ -599,15 +634,22 @@ main(int ac, char **av)
|
||||
exit(1);
|
||||
}
|
||||
/* Expand ~ in options.identity_files. */
|
||||
/* XXX mem-leaks */
|
||||
for (i = 0; i < options.num_identity_files; i++)
|
||||
options.identity_files[i] =
|
||||
tilde_expand_filename(options.identity_files[i], original_real_uid);
|
||||
|
||||
for (i = 0; i < options.num_identity_files2; i++)
|
||||
options.identity_files2[i] =
|
||||
tilde_expand_filename(options.identity_files2[i], original_real_uid);
|
||||
/* Expand ~ in known host file names. */
|
||||
options.system_hostfile = tilde_expand_filename(options.system_hostfile,
|
||||
original_real_uid);
|
||||
original_real_uid);
|
||||
options.user_hostfile = tilde_expand_filename(options.user_hostfile,
|
||||
original_real_uid);
|
||||
original_real_uid);
|
||||
options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2,
|
||||
original_real_uid);
|
||||
options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2,
|
||||
original_real_uid);
|
||||
|
||||
/* Log into the remote system. This never returns if the login fails. */
|
||||
ssh_login(host_private_key_loaded, host_private_key,
|
||||
@ -617,6 +659,62 @@ main(int ac, char **av)
|
||||
if (host_private_key_loaded)
|
||||
RSA_free(host_private_key); /* Destroys contents safely */
|
||||
|
||||
exit_status = compat20 ? ssh_session2() : ssh_session();
|
||||
packet_close();
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
void
|
||||
x11_get_proto(char *proto, int proto_len, char *data, int data_len)
|
||||
{
|
||||
char line[512];
|
||||
FILE *f;
|
||||
int got_data = 0, i;
|
||||
|
||||
#ifdef XAUTH_PATH
|
||||
/* Try to get Xauthority information for the display. */
|
||||
snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null",
|
||||
XAUTH_PATH, getenv("DISPLAY"));
|
||||
f = popen(line, "r");
|
||||
if (f && fgets(line, sizeof(line), f) &&
|
||||
sscanf(line, "%*s %s %s", proto, data) == 2)
|
||||
got_data = 1;
|
||||
if (f)
|
||||
pclose(f);
|
||||
#endif /* XAUTH_PATH */
|
||||
/*
|
||||
* If we didn't get authentication data, just make up some
|
||||
* data. The forwarding code will check the validity of the
|
||||
* response anyway, and substitute this data. The X11
|
||||
* server, however, will ignore this fake data and use
|
||||
* whatever authentication mechanisms it was using otherwise
|
||||
* for the local connection.
|
||||
*/
|
||||
if (!got_data) {
|
||||
u_int32_t rand = 0;
|
||||
|
||||
strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 4 == 0)
|
||||
rand = arc4random();
|
||||
snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff);
|
||||
rand >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ssh_session(void)
|
||||
{
|
||||
int type;
|
||||
int i;
|
||||
int plen;
|
||||
int interactive = 0;
|
||||
int have_tty = 0;
|
||||
struct winsize ws;
|
||||
int authfd;
|
||||
char *cp;
|
||||
|
||||
/* Enable compression if requested. */
|
||||
if (options.compression) {
|
||||
debug("Requesting compression at level %d.", options.compression_level);
|
||||
@ -670,7 +768,7 @@ main(int ac, char **av)
|
||||
type = packet_read(&plen);
|
||||
if (type == SSH_SMSG_SUCCESS) {
|
||||
interactive = 1;
|
||||
have_pty = 1;
|
||||
have_tty = 1;
|
||||
} else if (type == SSH_SMSG_FAILURE)
|
||||
log("Warning: Remote host failed or refused to allocate a pseudo tty.");
|
||||
else
|
||||
@ -678,56 +776,22 @@ main(int ac, char **av)
|
||||
}
|
||||
/* Request X11 forwarding if enabled and DISPLAY is set. */
|
||||
if (options.forward_x11 && getenv("DISPLAY") != NULL) {
|
||||
char line[512], proto[512], data[512];
|
||||
FILE *f;
|
||||
int forwarded = 0, got_data = 0, i;
|
||||
|
||||
#ifdef XAUTH_PATH
|
||||
/* Try to get Xauthority information for the display. */
|
||||
snprintf(line, sizeof line, "%.100s list %.200s 2>/dev/null",
|
||||
XAUTH_PATH, getenv("DISPLAY"));
|
||||
f = popen(line, "r");
|
||||
if (f && fgets(line, sizeof(line), f) &&
|
||||
sscanf(line, "%*s %s %s", proto, data) == 2)
|
||||
got_data = 1;
|
||||
if (f)
|
||||
pclose(f);
|
||||
#endif /* XAUTH_PATH */
|
||||
/*
|
||||
* If we didn't get authentication data, just make up some
|
||||
* data. The forwarding code will check the validity of the
|
||||
* response anyway, and substitute this data. The X11
|
||||
* server, however, will ignore this fake data and use
|
||||
* whatever authentication mechanisms it was using otherwise
|
||||
* for the local connection.
|
||||
*/
|
||||
if (!got_data) {
|
||||
u_int32_t rand = 0;
|
||||
|
||||
strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (i % 4 == 0)
|
||||
rand = arc4random();
|
||||
snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
|
||||
rand >>= 8;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Got local authentication reasonable information. Request
|
||||
* forwarding with authentication spoofing.
|
||||
*/
|
||||
char proto[512], data[512];
|
||||
/* Get reasonable local authentication information. */
|
||||
x11_get_proto(proto, sizeof proto, data, sizeof data);
|
||||
/* Request forwarding with authentication spoofing. */
|
||||
debug("Requesting X11 forwarding with authentication spoofing.");
|
||||
x11_request_forwarding_with_spoofing(proto, data);
|
||||
x11_request_forwarding_with_spoofing(0, proto, data);
|
||||
|
||||
/* Read response from the server. */
|
||||
type = packet_read(&plen);
|
||||
if (type == SSH_SMSG_SUCCESS) {
|
||||
forwarded = 1;
|
||||
interactive = 1;
|
||||
} else if (type == SSH_SMSG_FAILURE)
|
||||
} else if (type == SSH_SMSG_FAILURE) {
|
||||
log("Warning: Remote host denied X11 forwarding.");
|
||||
else
|
||||
} else {
|
||||
packet_disconnect("Protocol error waiting for X11 forwarding");
|
||||
}
|
||||
}
|
||||
/* Tell the packet module whether this is an interactive session. */
|
||||
packet_set_interactive(interactive, options.keepalives);
|
||||
@ -757,7 +821,7 @@ main(int ac, char **av)
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host_port);
|
||||
channel_request_local_forwarding(options.local_forwards[i].port,
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host_port,
|
||||
options.gateway_ports);
|
||||
}
|
||||
@ -770,11 +834,11 @@ main(int ac, char **av)
|
||||
options.remote_forwards[i].host_port);
|
||||
channel_request_remote_forwarding(options.remote_forwards[i].port,
|
||||
options.remote_forwards[i].host,
|
||||
options.remote_forwards[i].host_port);
|
||||
options.remote_forwards[i].host_port);
|
||||
}
|
||||
|
||||
/* If requested, let ssh continue in the background. */
|
||||
if (fork_after_authentication_flag)
|
||||
if (fork_after_authentication_flag)
|
||||
if (daemon(1, 1) < 0)
|
||||
fatal("daemon() failed: %.200s", strerror(errno));
|
||||
|
||||
@ -799,11 +863,114 @@ main(int ac, char **av)
|
||||
}
|
||||
|
||||
/* Enter the interactive session. */
|
||||
exit_status = client_loop(have_pty, tty_flag ? options.escape_char : -1);
|
||||
|
||||
/* Close the connection to the remote host. */
|
||||
packet_close();
|
||||
|
||||
/* Exit with the status returned by the program on the remote side. */
|
||||
exit(exit_status);
|
||||
return client_loop(have_tty, tty_flag ? options.escape_char : -1);
|
||||
}
|
||||
|
||||
void
|
||||
init_local_fwd(void)
|
||||
{
|
||||
int i;
|
||||
/* Initiate local TCP/IP port forwardings. */
|
||||
for (i = 0; i < options.num_local_forwards; i++) {
|
||||
debug("Connections to local port %d forwarded to remote address %.200s:%d",
|
||||
options.local_forwards[i].port,
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host_port);
|
||||
channel_request_local_forwarding(options.local_forwards[i].port,
|
||||
options.local_forwards[i].host,
|
||||
options.local_forwards[i].host_port,
|
||||
options.gateway_ports);
|
||||
}
|
||||
}
|
||||
|
||||
extern void client_set_session_ident(int id);
|
||||
|
||||
void
|
||||
client_init(int id, void *arg)
|
||||
{
|
||||
int len;
|
||||
debug("client_init id %d arg %d", id, (int)arg);
|
||||
|
||||
if (no_shell_flag)
|
||||
goto done;
|
||||
|
||||
if (tty_flag) {
|
||||
struct winsize ws;
|
||||
char *cp;
|
||||
cp = getenv("TERM");
|
||||
if (!cp)
|
||||
cp = "";
|
||||
/* Store window size in the packet. */
|
||||
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
|
||||
memset(&ws, 0, sizeof(ws));
|
||||
|
||||
channel_request_start(id, "pty-req", 0);
|
||||
packet_put_cstring(cp);
|
||||
packet_put_int(ws.ws_col);
|
||||
packet_put_int(ws.ws_row);
|
||||
packet_put_int(ws.ws_xpixel);
|
||||
packet_put_int(ws.ws_ypixel);
|
||||
packet_put_cstring(""); /* XXX: encode terminal modes */
|
||||
packet_send();
|
||||
/* XXX wait for reply */
|
||||
}
|
||||
if (options.forward_x11 &&
|
||||
getenv("DISPLAY") != NULL) {
|
||||
char proto[512], data[512];
|
||||
/* Get reasonable local authentication information. */
|
||||
x11_get_proto(proto, sizeof proto, data, sizeof data);
|
||||
/* Request forwarding with authentication spoofing. */
|
||||
debug("Requesting X11 forwarding with authentication spoofing.");
|
||||
x11_request_forwarding_with_spoofing(id, proto, data);
|
||||
/* XXX wait for reply */
|
||||
}
|
||||
|
||||
len = buffer_len(&command);
|
||||
if (len > 0) {
|
||||
if (len > 900)
|
||||
len = 900;
|
||||
debug("Sending command: %.*s", len, buffer_ptr(&command));
|
||||
channel_request_start(id, "exec", 0);
|
||||
packet_put_string(buffer_ptr(&command), len);
|
||||
packet_send();
|
||||
} else {
|
||||
channel_request(id, "shell", 0);
|
||||
}
|
||||
/* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */
|
||||
done:
|
||||
/* register different callback, etc. XXX */
|
||||
client_set_session_ident(id);
|
||||
}
|
||||
|
||||
int
|
||||
ssh_session2(void)
|
||||
{
|
||||
int window, packetmax, id;
|
||||
int in = dup(STDIN_FILENO);
|
||||
int out = dup(STDOUT_FILENO);
|
||||
int err = dup(STDERR_FILENO);
|
||||
|
||||
if (in < 0 || out < 0 || err < 0)
|
||||
fatal("dump in/out/err failed");
|
||||
|
||||
/* should be pre-session */
|
||||
init_local_fwd();
|
||||
|
||||
window = 32*1024;
|
||||
if (tty_flag) {
|
||||
packetmax = window/8;
|
||||
} else {
|
||||
window *= 2;
|
||||
packetmax = window/2;
|
||||
}
|
||||
|
||||
id = channel_new(
|
||||
"session", SSH_CHANNEL_OPENING, in, out, err,
|
||||
window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session"));
|
||||
|
||||
|
||||
channel_open(id);
|
||||
channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0);
|
||||
|
||||
return client_loop(tty_flag, tty_flag ? options.escape_char : -1);
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
*
|
||||
*
|
||||
* ssh.h
|
||||
*
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
*
|
||||
* Created: Fri Mar 17 17:09:37 1995 ylo
|
||||
*
|
||||
*
|
||||
* Generic header file for ssh.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: ssh.h,v 1.34 2000/03/23 22:15:33 markus Exp $"); */
|
||||
/* RCSID("$Id: ssh.h,v 1.45 2000/05/08 17:12:16 markus Exp $"); */
|
||||
|
||||
#ifndef SSH_H
|
||||
#define SSH_H
|
||||
@ -23,6 +23,7 @@
|
||||
#include "cipher.h"
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* The default cipher used if IDEA is not supported by the remote host. It is
|
||||
* recommended that this be one of the mandatory ciphers (DES, 3DES), though
|
||||
* that is not required.
|
||||
@ -47,14 +48,16 @@
|
||||
/*
|
||||
* Major protocol version. Different version indicates major incompatiblity
|
||||
* that prevents communication.
|
||||
*/
|
||||
#define PROTOCOL_MAJOR 1
|
||||
|
||||
/*
|
||||
*
|
||||
* Minor protocol version. Different version indicates minor incompatibility
|
||||
* that does not prevent interoperation.
|
||||
*/
|
||||
#define PROTOCOL_MINOR 5
|
||||
#define PROTOCOL_MAJOR_1 1
|
||||
#define PROTOCOL_MINOR_1 5
|
||||
|
||||
/* We support both SSH1 and SSH2 */
|
||||
#define PROTOCOL_MAJOR_2 2
|
||||
#define PROTOCOL_MINOR_2 0
|
||||
|
||||
/*
|
||||
* Name for the service. The port named by this service overrides the
|
||||
@ -70,6 +73,7 @@
|
||||
* world-readable.
|
||||
*/
|
||||
#define SSH_SYSTEM_HOSTFILE ETCDIR "/ssh_known_hosts"
|
||||
#define SSH_SYSTEM_HOSTFILE2 ETCDIR "/ssh_known_hosts2"
|
||||
|
||||
/*
|
||||
* Of these, ssh_host_key must be readable only by root, whereas ssh_config
|
||||
@ -78,6 +82,7 @@
|
||||
#define HOST_KEY_FILE ETCDIR "/ssh_host_key"
|
||||
#define SERVER_CONFIG_FILE ETCDIR "/sshd_config"
|
||||
#define HOST_CONFIG_FILE ETCDIR "/ssh_config"
|
||||
#define HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key"
|
||||
|
||||
#define SSH_PROGRAM "/usr/bin/ssh"
|
||||
|
||||
@ -99,12 +104,14 @@
|
||||
* contain anything particularly secret.
|
||||
*/
|
||||
#define SSH_USER_HOSTFILE "~/.ssh/known_hosts"
|
||||
#define SSH_USER_HOSTFILE2 "~/.ssh/known_hosts2"
|
||||
|
||||
/*
|
||||
* Name of the default file containing client-side authentication key. This
|
||||
* file should only be readable by the user him/herself.
|
||||
*/
|
||||
#define SSH_CLIENT_IDENTITY ".ssh/identity"
|
||||
#define SSH_CLIENT_ID_DSA ".ssh/id_dsa"
|
||||
|
||||
/*
|
||||
* Configuration file in user\'s home directory. This file need not be
|
||||
@ -123,6 +130,7 @@
|
||||
* running as root.)
|
||||
*/
|
||||
#define SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys"
|
||||
#define SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2"
|
||||
|
||||
/*
|
||||
* Per-user and system-wide ssh "rc" files. These files are executed with
|
||||
@ -259,7 +267,7 @@
|
||||
* information is not available. This must be called before record_login.
|
||||
* The host from which the user logged in is stored in buf.
|
||||
*/
|
||||
unsigned long
|
||||
unsigned long
|
||||
get_last_login_time(uid_t uid, const char *logname,
|
||||
char *buf, unsigned int bufsize);
|
||||
|
||||
@ -267,15 +275,15 @@ get_last_login_time(uid_t uid, const char *logname,
|
||||
* Records that the user has logged in. This does many things normally done
|
||||
* by login(1).
|
||||
*/
|
||||
void
|
||||
record_login(int pid, const char *ttyname, const char *user, uid_t uid,
|
||||
void
|
||||
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
const char *host, struct sockaddr *addr);
|
||||
|
||||
/*
|
||||
* Records that the user has logged out. This does many thigs normally done
|
||||
* by login(1) or init.
|
||||
*/
|
||||
void record_logout(int pid, const char *ttyname);
|
||||
void record_logout(pid_t pid, const char *ttyname);
|
||||
|
||||
/*------------ definitions for sshconnect.c ----------*/
|
||||
|
||||
@ -288,7 +296,7 @@ void record_logout(int pid, const char *ttyname);
|
||||
* and zero on failure. If the connection is successful, this calls
|
||||
* packet_set_connection for the connection.
|
||||
*/
|
||||
int
|
||||
int
|
||||
ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
|
||||
u_short port, int connection_attempts,
|
||||
int anonymous, uid_t original_real_uid,
|
||||
@ -303,7 +311,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
|
||||
* references from the packet module).
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
ssh_login(int host_key_valid, RSA * host_key, const char *host,
|
||||
struct sockaddr * hostaddr, uid_t original_real_uid);
|
||||
|
||||
@ -320,7 +328,7 @@ int auth_rhosts(struct passwd * pw, const char *client_user);
|
||||
* Tries to authenticate the user using the .rhosts file and the host using
|
||||
* its host key. Returns true if authentication succeeds.
|
||||
*/
|
||||
int
|
||||
int
|
||||
auth_rhosts_rsa(struct passwd * pw, const char *client_user, RSA* client_host_key);
|
||||
|
||||
/*
|
||||
@ -383,36 +391,6 @@ int auth_rsa_challenge_dialog(RSA *pk);
|
||||
*/
|
||||
char *read_passphrase(const char *prompt, int from_stdin);
|
||||
|
||||
/*
|
||||
* Saves the authentication (private) key in a file, encrypting it with
|
||||
* passphrase. The identification of the file (lowest 64 bits of n) will
|
||||
* precede the key to provide identification of the key without needing a
|
||||
* passphrase.
|
||||
*/
|
||||
int
|
||||
save_private_key(const char *filename, const char *passphrase,
|
||||
RSA * private_key, const char *comment);
|
||||
|
||||
/*
|
||||
* Loads the public part of the key file (public key and comment). Returns 0
|
||||
* if an error occurred; zero if the public key was successfully read. The
|
||||
* comment of the key is returned in comment_return if it is non-NULL; the
|
||||
* caller must free the value with xfree.
|
||||
*/
|
||||
int
|
||||
load_public_key(const char *filename, RSA * pub,
|
||||
char **comment_return);
|
||||
|
||||
/*
|
||||
* Loads the private key from the file. Returns 0 if an error is encountered
|
||||
* (file does not exist or is not readable, or passphrase is bad). This
|
||||
* initializes the private key. The comment of the key is returned in
|
||||
* comment_return if it is non-NULL; the caller must free the value with
|
||||
* xfree.
|
||||
*/
|
||||
int
|
||||
load_private_key(const char *filename, const char *passphrase,
|
||||
RSA * private_key, char **comment_return);
|
||||
|
||||
/*------------ Definitions for logging. -----------------------*/
|
||||
|
||||
@ -469,174 +447,7 @@ void fatal_add_cleanup(void (*proc) (void *context), void *context);
|
||||
/* Removes a cleanup function to be called at fatal(). */
|
||||
void fatal_remove_cleanup(void (*proc) (void *context), void *context);
|
||||
|
||||
/*---------------- definitions for channels ------------------*/
|
||||
|
||||
/* Sets specific protocol options. */
|
||||
void channel_set_options(int hostname_in_open);
|
||||
|
||||
/*
|
||||
* Allocate a new channel object and set its type and socket. Remote_name
|
||||
* must have been allocated with xmalloc; this will free it when the channel
|
||||
* is freed.
|
||||
*/
|
||||
int channel_allocate(int type, int sock, char *remote_name);
|
||||
|
||||
/* Free the channel and close its socket. */
|
||||
void channel_free(int channel);
|
||||
|
||||
/* Add any bits relevant to channels in select bitmasks. */
|
||||
void channel_prepare_select(fd_set * readset, fd_set * writeset);
|
||||
|
||||
/*
|
||||
* After select, perform any appropriate operations for channels which have
|
||||
* events pending.
|
||||
*/
|
||||
void channel_after_select(fd_set * readset, fd_set * writeset);
|
||||
|
||||
/* If there is data to send to the connection, send some of it now. */
|
||||
void channel_output_poll(void);
|
||||
|
||||
/*
|
||||
* This is called when a packet of type CHANNEL_DATA has just been received.
|
||||
* The message type has already been consumed, but channel number and data is
|
||||
* still there.
|
||||
*/
|
||||
void channel_input_data(int payload_len);
|
||||
|
||||
/* Returns true if no channel has too much buffered data. */
|
||||
int channel_not_very_much_buffered_data(void);
|
||||
|
||||
/* This is called after receiving CHANNEL_CLOSE. */
|
||||
void channel_input_close(void);
|
||||
|
||||
/* This is called after receiving CHANNEL_CLOSE_CONFIRMATION. */
|
||||
void channel_input_close_confirmation(void);
|
||||
|
||||
/* This is called after receiving CHANNEL_OPEN_CONFIRMATION. */
|
||||
void channel_input_open_confirmation(void);
|
||||
|
||||
/* This is called after receiving CHANNEL_OPEN_FAILURE from the other side. */
|
||||
void channel_input_open_failure(void);
|
||||
|
||||
/* This closes any sockets that are listening for connections; this removes
|
||||
any unix domain sockets. */
|
||||
void channel_stop_listening(void);
|
||||
|
||||
/*
|
||||
* Closes the sockets of all channels. This is used to close extra file
|
||||
* descriptors after a fork.
|
||||
*/
|
||||
void channel_close_all(void);
|
||||
|
||||
/* Returns the maximum file descriptor number used by the channels. */
|
||||
int channel_max_fd(void);
|
||||
|
||||
/* Returns true if there is still an open channel over the connection. */
|
||||
int channel_still_open(void);
|
||||
|
||||
/*
|
||||
* Returns a string containing a list of all open channels. The list is
|
||||
* suitable for displaying to the user. It uses crlf instead of newlines.
|
||||
* The caller should free the string with xfree.
|
||||
*/
|
||||
char *channel_open_message(void);
|
||||
|
||||
/*
|
||||
* Initiate forwarding of connections to local port "port" through the secure
|
||||
* channel to host:port from remote side. This never returns if there was an
|
||||
* error.
|
||||
*/
|
||||
void
|
||||
channel_request_local_forwarding(u_short port, const char *host,
|
||||
u_short remote_port, int gateway_ports);
|
||||
|
||||
/*
|
||||
* Initiate forwarding of connections to port "port" on remote host through
|
||||
* the secure channel to host:port from local side. This never returns if
|
||||
* there was an error. This registers that open requests for that port are
|
||||
* permitted.
|
||||
*/
|
||||
void
|
||||
channel_request_remote_forwarding(u_short port, const char *host,
|
||||
u_short remote_port);
|
||||
|
||||
/*
|
||||
* Permits opening to any host/port in SSH_MSG_PORT_OPEN. This is usually
|
||||
* called by the server, because the user could connect to any port anyway,
|
||||
* and the server has no way to know but to trust the client anyway.
|
||||
*/
|
||||
void channel_permit_all_opens(void);
|
||||
|
||||
/*
|
||||
* This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
|
||||
* listening for the port, and sends back a success reply (or disconnect
|
||||
* message if there was an error). This never returns if there was an error.
|
||||
*/
|
||||
void channel_input_port_forward_request(int is_root);
|
||||
|
||||
/*
|
||||
* This is called after receiving PORT_OPEN message. This attempts to
|
||||
* connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
|
||||
* or CHANNEL_OPEN_FAILURE.
|
||||
*/
|
||||
void channel_input_port_open(int payload_len);
|
||||
|
||||
/*
|
||||
* Creates a port for X11 connections, and starts listening for it. Returns
|
||||
* the display name, or NULL if an error was encountered.
|
||||
*/
|
||||
char *x11_create_display(int screen);
|
||||
|
||||
/*
|
||||
* Creates an internet domain socket for listening for X11 connections.
|
||||
* Returns a suitable value for the DISPLAY variable, or NULL if an error
|
||||
* occurs.
|
||||
*/
|
||||
char *x11_create_display_inet(int screen, int x11_display_offset);
|
||||
|
||||
/*
|
||||
* This is called when SSH_SMSG_X11_OPEN is received. The packet contains
|
||||
* the remote channel number. We should do whatever we want, and respond
|
||||
* with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
|
||||
*/
|
||||
void x11_input_open(int payload_len);
|
||||
|
||||
/*
|
||||
* Requests forwarding of X11 connections. This should be called on the
|
||||
* client only.
|
||||
*/
|
||||
void x11_request_forwarding(void);
|
||||
|
||||
/*
|
||||
* Requests forwarding for X11 connections, with authentication spoofing.
|
||||
* This should be called in the client only.
|
||||
*/
|
||||
void x11_request_forwarding_with_spoofing(const char *proto, const char *data);
|
||||
|
||||
/* Sends a message to the server to request authentication fd forwarding. */
|
||||
void auth_request_forwarding(void);
|
||||
|
||||
/*
|
||||
* Returns the name of the forwarded authentication socket. Returns NULL if
|
||||
* there is no forwarded authentication socket. The returned value points to
|
||||
* a static buffer.
|
||||
*/
|
||||
char *auth_get_socket_name(void);
|
||||
|
||||
/*
|
||||
* This if called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
|
||||
* This starts forwarding authentication requests.
|
||||
*/
|
||||
void auth_input_request_forwarding(struct passwd * pw);
|
||||
|
||||
/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
|
||||
void auth_input_open_request(void);
|
||||
|
||||
/*
|
||||
* Returns true if the given string matches the pattern (which may contain ?
|
||||
* and * as wildcards), and zero if it does not match.
|
||||
*/
|
||||
int match_pattern(const char *s, const char *pattern);
|
||||
/* ---- misc */
|
||||
|
||||
/*
|
||||
* Expands tildes in the file name. Returns data allocated by xmalloc.
|
||||
@ -651,7 +462,8 @@ char *tilde_expand_filename(const char *filename, uid_t my_uid);
|
||||
* (of the child program), and reads from stdout and stderr (of the child
|
||||
* program).
|
||||
*/
|
||||
void server_loop(int pid, int fdin, int fdout, int fderr);
|
||||
void server_loop(pid_t pid, int fdin, int fdout, int fderr);
|
||||
void server_loop2(void);
|
||||
|
||||
/* Client side main loop for the interactive session. */
|
||||
int client_loop(int have_pty, int escape_char);
|
||||
@ -695,14 +507,14 @@ int auth_krb4_password(struct passwd * pw, const char *password);
|
||||
int auth_krb4_tgt(struct passwd * pw, const char *string);
|
||||
int auth_afs_token(struct passwd * pw, const char *token_string);
|
||||
|
||||
int creds_to_radix(CREDENTIALS * creds, unsigned char *buf);
|
||||
int creds_to_radix(CREDENTIALS * creds, unsigned char *buf, size_t buflen);
|
||||
int radix_to_creds(const char *buf, CREDENTIALS * creds);
|
||||
#endif /* AFS */
|
||||
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifdef SKEY
|
||||
#include <skey.h>
|
||||
#include <opie.h>
|
||||
char *skey_fake_keyinfo(char *username);
|
||||
int auth_skey_password(struct passwd * pw, const char *password);
|
||||
#endif /* SKEY */
|
||||
|
@ -28,5 +28,6 @@
|
||||
# StrictHostKeyChecking no
|
||||
# IdentityFile ~/.ssh/identity
|
||||
# Port 22
|
||||
# Protocol 2,1
|
||||
# Cipher blowfish
|
||||
# EscapeChar ~
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,7 @@
|
||||
* Code to connect to a remote host, and to perform the client side of the
|
||||
* login (authentication) dialog.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
@ -362,7 +363,7 @@ try_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
|
||||
|
||||
#ifdef KRB4
|
||||
int
|
||||
try_kerberos_authentication()
|
||||
try_krb4_authentication()
|
||||
{
|
||||
KTEXT_ST auth; /* Kerberos data */
|
||||
char *reply;
|
||||
@ -405,7 +406,7 @@ try_kerberos_authentication()
|
||||
des_key_sched((des_cblock *) cred.session, schedule);
|
||||
|
||||
/* Send authentication info to server. */
|
||||
packet_start(SSH_CMSG_AUTH_KERBEROS);
|
||||
packet_start(SSH_CMSG_AUTH_KRB4);
|
||||
packet_put_string((char *) auth.dat, auth.length);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
@ -430,13 +431,13 @@ try_kerberos_authentication()
|
||||
type = packet_read(&plen);
|
||||
switch (type) {
|
||||
case SSH_SMSG_FAILURE:
|
||||
/* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
|
||||
/* Should really be SSH_SMSG_AUTH_KRB4_FAILURE */
|
||||
debug("Kerberos V4 authentication failed.");
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
|
||||
/* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
|
||||
case SSH_SMSG_AUTH_KRB4_RESPONSE:
|
||||
/* SSH_SMSG_AUTH_KRB4_SUCCESS */
|
||||
debug("Kerberos V4 authentication accepted.");
|
||||
|
||||
/* Get server's response. */
|
||||
@ -479,7 +480,7 @@ try_kerberos_authentication()
|
||||
|
||||
#ifdef AFS
|
||||
int
|
||||
send_kerberos_tgt()
|
||||
send_krb4_tgt()
|
||||
{
|
||||
CREDENTIALS *creds;
|
||||
char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
|
||||
@ -508,7 +509,7 @@ send_kerberos_tgt()
|
||||
creds_to_radix(creds, (unsigned char *)buffer, sizeof buffer);
|
||||
xfree(creds);
|
||||
|
||||
packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
|
||||
packet_start(SSH_CMSG_HAVE_KRB4_TGT);
|
||||
packet_put_string(buffer, strlen(buffer));
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
@ -927,11 +928,11 @@ ssh_userauth(
|
||||
|
||||
#ifdef AFS
|
||||
/* Try Kerberos tgt passing if the server supports it. */
|
||||
if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
|
||||
options.kerberos_tgt_passing) {
|
||||
if ((supported_authentications & (1 << SSH_PASS_KRB4_TGT)) &&
|
||||
options.krb4_tgt_passing) {
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
|
||||
(void) send_kerberos_tgt();
|
||||
(void) send_krb4_tgt();
|
||||
}
|
||||
/* Try AFS token passing if the server supports it. */
|
||||
if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
|
||||
@ -943,10 +944,10 @@ ssh_userauth(
|
||||
#endif /* AFS */
|
||||
|
||||
#ifdef KRB4
|
||||
if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
|
||||
options.kerberos_authentication) {
|
||||
if ((supported_authentications & (1 << SSH_AUTH_KRB4)) &&
|
||||
options.krb4_authentication) {
|
||||
debug("Trying Kerberos authentication.");
|
||||
if (try_kerberos_authentication()) {
|
||||
if (try_krb4_authentication()) {
|
||||
/* The server should respond with success or failure. */
|
||||
type = packet_read(&payload_len);
|
||||
if (type == SSH_SMSG_SUCCESS)
|
||||
@ -957,6 +958,35 @@ ssh_userauth(
|
||||
}
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifdef KRB5
|
||||
if ((supported_authentications & (1 << SSH_AUTH_KRB5)) &&
|
||||
options.krb5_authentication){
|
||||
krb5_context ssh_context = NULL;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
|
||||
debug("Trying Kerberos V5 authentication.");
|
||||
|
||||
if (try_krb5_authentication(&ssh_context, &auth_context)) {
|
||||
type = packet_read(&payload_len);
|
||||
if (type == SSH_SMSG_SUCCESS) {
|
||||
if ((supported_authentications & (1 << SSH_PASS_KRB5_TGT)) &&
|
||||
options.krb5_tgt_passing) {
|
||||
if (options.cipher == SSH_CIPHER_NONE)
|
||||
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
|
||||
send_krb5_tgt(ssh_context, auth_context);
|
||||
|
||||
}
|
||||
krb5_auth_con_free(ssh_context, auth_context);
|
||||
krb5_free_context(ssh_context);
|
||||
return;
|
||||
}
|
||||
if (type != SSH_SMSG_FAILURE)
|
||||
packet_disconnect("Protocol error: got %d in response to Kerberos5 auth", type);
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* KRB5 */
|
||||
|
||||
/*
|
||||
* Use rhosts authentication if running in privileged socket and we
|
||||
* do not wish to remain anonymous.
|
||||
|
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.\" Created: Sat Apr 22 21:55:14 1995 ylo
|
||||
.\"
|
||||
.\" $Id: sshd.8,v 1.37 2000/03/24 03:04:46 brad Exp $
|
||||
.\" $Id: sshd.8,v 1.51 2000/05/08 17:42:31 hugh Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 25, 1999
|
||||
@ -28,11 +28,11 @@
|
||||
.Op Fl k Ar key_gen_time
|
||||
.Op Fl p Ar port
|
||||
.Op Fl V Ar client_protocol_id
|
||||
.Sh DESCRIPTION
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
(Secure Shell Daemon) is the daemon program for
|
||||
(Secure Shell Daemon) is the daemon program for
|
||||
.Xr ssh 1 .
|
||||
Together these programs replace rlogin and rsh programs, and
|
||||
Together these programs replace rlogin and rsh, and
|
||||
provide secure encrypted communications between two untrusted hosts
|
||||
over an insecure network.
|
||||
The programs are intended to be as easy to
|
||||
@ -47,9 +47,14 @@ daemon for each incoming connection.
|
||||
The forked daemons handle
|
||||
key exchange, encryption, authentication, command execution,
|
||||
and data exchange.
|
||||
.Pp
|
||||
This implementation of
|
||||
.Nm
|
||||
supports both SSH protocol version 1 and 2 simultaneously.
|
||||
.Nm
|
||||
works as follows.
|
||||
.Pp
|
||||
.Ss SSH protocol version 1
|
||||
.Pp
|
||||
Each host has a host-specific RSA key
|
||||
(normally 1024 bits) used to identify the host.
|
||||
Additionally, when
|
||||
@ -57,20 +62,20 @@ the daemon starts, it generates a server RSA key (normally 768 bits).
|
||||
This key is normally regenerated every hour if it has been used, and
|
||||
is never stored on disk.
|
||||
.Pp
|
||||
Whenever a client connects the daemon, the daemon sends its host
|
||||
and server public keys to the client.
|
||||
Whenever a client connects the daemon responds with its public
|
||||
host and server keys.
|
||||
The client compares the
|
||||
host key against its own database to verify that it has not changed.
|
||||
RSA host key against its own database to verify that it has not changed.
|
||||
The client then generates a 256 bit random number.
|
||||
It encrypts this
|
||||
random number using both the host key and the server key, and sends
|
||||
the encrypted number to the server.
|
||||
Both sides then start to use this
|
||||
Both sides then use this
|
||||
random number as a session key which is used to encrypt all further
|
||||
communications in the session.
|
||||
The rest of the session is encrypted
|
||||
using a conventional cipher, currently Blowfish and 3DES, with 3DES
|
||||
being is used by default.
|
||||
using a conventional cipher, currently Blowfish or 3DES, with 3DES
|
||||
being used by default.
|
||||
The client selects the encryption algorithm
|
||||
to use from those offered by the server.
|
||||
.Pp
|
||||
@ -96,7 +101,29 @@ are disabled (thus completely disabling
|
||||
.Xr rlogin 1
|
||||
and
|
||||
.Xr rsh 1
|
||||
into that machine).
|
||||
into the machine).
|
||||
.Pp
|
||||
.Ss SSH protocol version 2
|
||||
.Pp
|
||||
Version 2 works similar:
|
||||
Each host has a host-specific DSA key used to identify the host.
|
||||
However, when the daemon starts, it does not generate a server key.
|
||||
Forward security is provided through a Diffie-Hellman key agreement.
|
||||
This key agreement results in a shared session key.
|
||||
The rest of the session is encrypted
|
||||
using a symmetric cipher, currently
|
||||
Blowfish, 3DES or CAST128 in CBC mode or Arcfour.
|
||||
The client selects the encryption algorithm
|
||||
to use from those offered by the server.
|
||||
Additionally, session integrity is provided
|
||||
through a cryptographic message authentication code
|
||||
(hmac-sha1 or hmac-md5).
|
||||
.Pp
|
||||
Protocol version 2 provides a public key based
|
||||
user authentication method (DSAAuthentication)
|
||||
and conventional password authentication.
|
||||
.Pp
|
||||
.Ss Command execution and data forwarding
|
||||
.Pp
|
||||
If the client successfully authenticates itself, a dialog for
|
||||
preparing the session is entered.
|
||||
@ -149,7 +176,7 @@ If the client fails to authenticate the user within
|
||||
this many seconds, the server disconnects and exits.
|
||||
A value of zero indicates no limit.
|
||||
.It Fl h Ar host_key_file
|
||||
Specifies the file from which the host key is read (default
|
||||
Specifies the file from which the RSA host key is read (default
|
||||
.Pa /etc/ssh/ssh_host_key ) .
|
||||
This option must be given if
|
||||
.Nm
|
||||
@ -158,7 +185,7 @@ host file is normally not readable by anyone but root).
|
||||
.It Fl i
|
||||
Specifies that
|
||||
.Nm
|
||||
is being run from inetd.
|
||||
is being run from inetd.
|
||||
.Nm
|
||||
is normally not run
|
||||
from inetd because it needs to generate the server key before it can
|
||||
@ -189,9 +216,9 @@ authentication, and termination of each connection is logged.
|
||||
Do not print an error message if RSA support is missing.
|
||||
.It Fl V Ar client_protocol_id
|
||||
SSH2 compatibility mode.
|
||||
When this options is specified
|
||||
When this option is specified
|
||||
.Nm
|
||||
assumes the client has sent the given version string
|
||||
assumes the client has sent the supplied version string
|
||||
and skips the
|
||||
Protocol Version Identification Exchange.
|
||||
.It Fl 4
|
||||
@ -205,7 +232,7 @@ to use IPv6 addresses only.
|
||||
.El
|
||||
.Sh CONFIGURATION FILE
|
||||
.Nm
|
||||
reads configuration data from
|
||||
reads configuration data from
|
||||
.Pa /etc/ssh/sshd_config
|
||||
(or the file specified with
|
||||
.Fl f
|
||||
@ -247,6 +274,11 @@ wildcards in the patterns.
|
||||
Only user names are valid, a numerical user ID isn't recognized.
|
||||
By default login is allowed regardless of the user name.
|
||||
.Pp
|
||||
.It Cm Ciphers
|
||||
Specifies the ciphers allowed for protocol version 2.
|
||||
Multiple ciphers must be comma-separated.
|
||||
The default is
|
||||
.Dq 3des-cbc,blowfish-cbc,arcfour,cast128-cbc .
|
||||
.It Cm CheckMail
|
||||
Specifies whether
|
||||
.Nm
|
||||
@ -301,24 +333,45 @@ and
|
||||
can be used as wildcards in the patterns.
|
||||
Only user names are valid, a numerical user ID isn't recognized.
|
||||
By default login is allowed regardless of the user name.
|
||||
.It Cm HostKey
|
||||
Specifies the file containing the private host key (default
|
||||
.Pa /etc/ssh/ssh_host_key ) .
|
||||
.It Cm DSAAuthentication
|
||||
Specifies whether DSA authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 2 only.
|
||||
.It Cm GatewayPorts
|
||||
Specifies whether remote hosts are allowed to connect to ports
|
||||
forwarded for the client.
|
||||
The argument must be
|
||||
.Dq yes
|
||||
or
|
||||
.Dq no .
|
||||
The default is
|
||||
.Dq no .
|
||||
.It Cm HostDsaKey
|
||||
Specifies the file containing the private DSA host key (default
|
||||
.Pa /etc/ssh/ssh_host_dsa_key )
|
||||
used by SSH protocol 2.0.
|
||||
Note that
|
||||
.Nm
|
||||
does not start if this file is group/world-accessible.
|
||||
disables protocol 2.0 if this file is group/world-accessible.
|
||||
.It Cm HostKey
|
||||
Specifies the file containing the private RSA host key (default
|
||||
.Pa /etc/ssh/ssh_host_key )
|
||||
used by SSH protocols 1.3 and 1.5.
|
||||
Note that
|
||||
.Nm
|
||||
disables protocols 1.3 and 1.5 if this file is group/world-accessible.
|
||||
.It Cm IgnoreRhosts
|
||||
Specifies that
|
||||
.Pa .rhosts
|
||||
and
|
||||
and
|
||||
.Pa .shosts
|
||||
files will not be used in authentication.
|
||||
.Pa /etc/hosts.equiv
|
||||
and
|
||||
.Pa /etc/ssh/shosts.equiv
|
||||
.Pa /etc/shosts.equiv
|
||||
are still used.
|
||||
The default is
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm IgnoreUserKnownHosts
|
||||
Specifies whether
|
||||
@ -337,7 +390,7 @@ of the machines will be properly noticed.
|
||||
However, this means that
|
||||
connections will die if the route is down temporarily, and some people
|
||||
find it annoying.
|
||||
On the other hand, if keepalives are not send,
|
||||
On the other hand, if keepalives are not sent,
|
||||
sessions may hang indefinitely on the server, leaving
|
||||
.Dq ghost
|
||||
users and consuming server resources.
|
||||
@ -369,7 +422,7 @@ Default is
|
||||
.Dq yes .
|
||||
.It Cm KerberosTgtPassing
|
||||
Specifies whether a Kerberos TGT may be forwarded to the server.
|
||||
Default is
|
||||
Default is
|
||||
.Dq no ,
|
||||
as this only works when the Kerberos KDC is actually an AFS kaserver.
|
||||
.It Cm KerberosTicketCleanup
|
||||
@ -412,6 +465,7 @@ and is not recommended.
|
||||
Specifies whether password authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to both protocol version 1 and 2.
|
||||
.It Cm PermitEmptyPasswords
|
||||
When password authentication is allowed, it specifies whether the
|
||||
server allows login to accounts with empty password strings.
|
||||
@ -437,6 +491,12 @@ option has been
|
||||
specified will be allowed regardless of the value of this setting
|
||||
(which may be useful for taking remote backups even if root login is
|
||||
normally not allowed).
|
||||
.It Cm PidFile
|
||||
Specifies the file that contains the process identifier of the
|
||||
.Nm
|
||||
daemon.
|
||||
The default is
|
||||
.Pa /var/run/sshd.pid .
|
||||
.It Cm Port
|
||||
Specifies the port number that
|
||||
.Nm
|
||||
@ -446,7 +506,7 @@ Multiple options of this type are permitted.
|
||||
.It Cm PrintMotd
|
||||
Specifies whether
|
||||
.Nm
|
||||
should print
|
||||
should print
|
||||
.Pa /etc/motd
|
||||
when a user logs in interactively.
|
||||
(On some systems it is also printed by the shell,
|
||||
@ -454,6 +514,17 @@ when a user logs in interactively.
|
||||
or equivalent.)
|
||||
The default is
|
||||
.Dq yes .
|
||||
.It Cm Protocol
|
||||
Specifies the protocol versions
|
||||
.Nm
|
||||
should support.
|
||||
The possible values are
|
||||
.Dq 1
|
||||
and
|
||||
.Dq 2 .
|
||||
Multiple versions must be comma-separated.
|
||||
The default is
|
||||
.Dq 1 .
|
||||
.It Cm RandomSeed
|
||||
Obsolete - accepted and ignored with a warning.
|
||||
Random number generation uses other techniques.
|
||||
@ -481,12 +552,13 @@ The default is
|
||||
Specifies whether pure RSA authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
Note that this option applies to protocol version 1 only.
|
||||
.It Cm ServerKeyBits
|
||||
Defines the number of bits in the server key.
|
||||
The minimum value is 512, and the default is 768.
|
||||
.It Cm SkeyAuthentication
|
||||
Specifies whether
|
||||
.Xr skey 1
|
||||
.Xr skey 1
|
||||
authentication is allowed.
|
||||
The default is
|
||||
.Dq yes .
|
||||
@ -536,12 +608,12 @@ does the following:
|
||||
.Bl -enum -offset indent
|
||||
.It
|
||||
If the login is on a tty, and no command has been specified,
|
||||
prints last login time and
|
||||
prints last login time and
|
||||
.Pa /etc/motd
|
||||
(unless prevented in the configuration file or by
|
||||
.Pa $HOME/.hushlogin ;
|
||||
see the
|
||||
.Sx FILES
|
||||
.Sx FILES
|
||||
section).
|
||||
.It
|
||||
If the login is on a tty, records login time.
|
||||
@ -577,10 +649,14 @@ authentication protocol and cookie (if applicable) in standard input.
|
||||
Runs user's shell or command.
|
||||
.El
|
||||
.Sh AUTHORIZED_KEYS FILE FORMAT
|
||||
The
|
||||
The
|
||||
.Pa $HOME/.ssh/authorized_keys
|
||||
file lists the RSA keys that are
|
||||
permitted for RSA authentication.
|
||||
permitted for RSA authentication in SSH protocols 1.3 and 1.5
|
||||
Similarly, the
|
||||
.Pa $HOME/.ssh/authorized_keys2
|
||||
file lists the DSA keys that are
|
||||
permitted for DSA authentication in SSH protocol 2.0.
|
||||
Each line of the file contains one
|
||||
key (empty lines and lines starting with a
|
||||
.Ql #
|
||||
@ -636,8 +712,8 @@ A quote may be included in the command by quoting it with a backslash.
|
||||
This option might be useful
|
||||
to restrict certain RSA keys to perform just a specific operation.
|
||||
An example might be a key that permits remote backups but nothing else.
|
||||
Notice that the client may specify TCP/IP and/or X11
|
||||
forwardings unless they are explicitly prohibited.
|
||||
Note that the client may specify TCP/IP and/or X11
|
||||
forwarding unless they are explicitly prohibited.
|
||||
.It Cm environment="NAME=value"
|
||||
Specifies that the string is to be added to the environment when
|
||||
logging in using this key.
|
||||
@ -666,10 +742,12 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula
|
||||
command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi
|
||||
.Ed
|
||||
.Sh SSH_KNOWN_HOSTS FILE FORMAT
|
||||
The
|
||||
.Pa /etc/ssh/ssh_known_hosts
|
||||
and
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
The
|
||||
.Pa /etc/ssh/ssh_known_hosts ,
|
||||
.Pa /etc/ssh/ssh_known_hosts2 ,
|
||||
.Pa $HOME/.ssh/known_hosts ,
|
||||
and
|
||||
.Pa $HOME/.ssh/known_hosts2
|
||||
files contain host public keys for all known hosts.
|
||||
The global file should
|
||||
be prepared by the administrator (optional), and the per-user file is
|
||||
@ -690,7 +768,7 @@ to indicate negation: if the host name matches a negated
|
||||
pattern, it is not accepted (by that line) even if it matched another
|
||||
pattern on the line.
|
||||
.Pp
|
||||
Bits, exponent, and modulus are taken directly from the host key; they
|
||||
Bits, exponent, and modulus are taken directly from the RSA host key; they
|
||||
can be obtained, e.g., from
|
||||
.Pa /etc/ssh/ssh_host_key.pub .
|
||||
The optional comment field continues to the end of the line, and is not used.
|
||||
@ -713,7 +791,7 @@ accepted if valid information can be found from either file.
|
||||
Note that the lines in these files are typically hundreds of characters
|
||||
long, and you definitely don't want to type in the host keys by hand.
|
||||
Rather, generate them by a script
|
||||
or by taking
|
||||
or by taking
|
||||
.Pa /etc/ssh/ssh_host_key.pub
|
||||
and adding the host names at the front.
|
||||
.Ss Examples
|
||||
@ -758,6 +836,21 @@ it being world-readable if the user's home directory resides on an NFS
|
||||
volume).
|
||||
It is recommended that it not be accessible by others.
|
||||
The format of this file is described above.
|
||||
Users will place the contents of their
|
||||
.Pa identity.pub
|
||||
files into this file, as described in
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Pa $HOME/.ssh/authorized_keys2
|
||||
Lists the DSA keys that can be used to log into the user's account.
|
||||
This file must be readable by root (which may on some machines imply
|
||||
it being world-readable if the user's home directory resides on an NFS
|
||||
volume).
|
||||
It is recommended that it not be accessible by others.
|
||||
The format of this file is described above.
|
||||
Users will place the contents of their
|
||||
.Pa id_dsa.pub
|
||||
files into this file, as described in
|
||||
.Xr ssh-keygen 1 .
|
||||
.It Pa "/etc/ssh/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
|
||||
These files are consulted when using rhosts with RSA host
|
||||
authentication to check the public key of the host.
|
||||
@ -770,7 +863,7 @@ should be world-readable, and
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
can but need not be world-readable.
|
||||
.It Pa /etc/nologin
|
||||
If this file exists,
|
||||
If this file exists,
|
||||
.Nm
|
||||
refuses to let anyone except root log in.
|
||||
The contents of the file
|
||||
@ -897,6 +990,7 @@ but with bugs removed and newer features re-added.
|
||||
Rapidly after the
|
||||
1.2.12 release, newer versions of the original ssh bore successively
|
||||
more restrictive licenses, and thus demand for a free version was born.
|
||||
.Pp
|
||||
This version of OpenSSH
|
||||
.Bl -bullet
|
||||
.It
|
||||
@ -906,10 +1000,10 @@ directly removed from the source code; any licensed or patented components
|
||||
are chosen from
|
||||
external libraries.
|
||||
.It
|
||||
has been updated to support ssh protocol 1.5, making it compatible with
|
||||
all other ssh protocol 1 clients and servers.
|
||||
has been updated to support SSH protocol 1.5 and 2, making it compatible with
|
||||
all other SSH clients and servers.
|
||||
.It
|
||||
contains added support for
|
||||
contains added support for
|
||||
.Xr kerberos 8
|
||||
authentication and ticket passing.
|
||||
.It
|
||||
@ -920,12 +1014,17 @@ supports one-time password authentication with
|
||||
The libraries described in
|
||||
.Xr ssl 8
|
||||
are required for proper operation.
|
||||
.Pp
|
||||
OpenSSH has been created by Aaron Campbell, Bob Beck, Markus Friedl,
|
||||
Niels Provos, Theo de Raadt, and Dug Song.
|
||||
.Pp
|
||||
The support for SSH protocol 2 was written by Markus Friedl.
|
||||
.Sh SEE ALSO
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1 ,
|
||||
.Xr scp 1 ,
|
||||
.Xr ssh 1 ,
|
||||
.Xr ssh-add 1 ,
|
||||
.Xr ssh-agent 1 ,
|
||||
.Xr ssh-keygen 1 ,
|
||||
.Xr ssl 8
|
||||
.Xr ssl 8 ,
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
Port 22
|
||||
#Protocol 2,1
|
||||
#ListenAddress 0.0.0.0
|
||||
#ListenAddress ::
|
||||
HostKey /etc/ssh/ssh_host_key
|
||||
|
Loading…
Reference in New Issue
Block a user