mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-11-27 05:46:36 +08:00
- OpenBSD CVS updates:
- [channels.c] repair x11-fwd - [sshconnect.c] fix passwd prompt for ssh2, less debugging output. - [clientloop.c compat.c dsa.c kex.c sshd.c] less debugging output - [kex.c kex.h sshconnect.c sshd.c] check for reasonable public DH values - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c] [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c] add Cipher and Protocol options to ssh/sshd, e.g.: ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers arcfour,3des-cbc' - [sshd.c] print 1.99 only if server supports both
This commit is contained in:
parent
efb4afe026
commit
78928793fb
18
ChangeLog
18
ChangeLog
@ -1,3 +1,21 @@
|
||||
20000412
|
||||
- OpenBSD CVS updates:
|
||||
- [channels.c]
|
||||
repair x11-fwd
|
||||
- [sshconnect.c]
|
||||
fix passwd prompt for ssh2, less debugging output.
|
||||
- [clientloop.c compat.c dsa.c kex.c sshd.c]
|
||||
less debugging output
|
||||
- [kex.c kex.h sshconnect.c sshd.c]
|
||||
check for reasonable public DH values
|
||||
- [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c]
|
||||
[readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c]
|
||||
add Cipher and Protocol options to ssh/sshd, e.g.:
|
||||
ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers
|
||||
arcfour,3des-cbc'
|
||||
- [sshd.c]
|
||||
print 1.99 only if server supports both
|
||||
|
||||
20000408
|
||||
- Avoid some compiler warnings in fake-get*.c
|
||||
- Add IPTOS macros for systems which lack them
|
||||
|
@ -1,4 +1,13 @@
|
||||
$Id: README.openssh2,v 1.2 2000/04/06 21:28:22 markus Exp $
|
||||
$Id: README.openssh2,v 1.3 2000/04/12 07:45:43 markus Exp $
|
||||
|
||||
howto:
|
||||
1) generate server key:
|
||||
$ umask 077
|
||||
$ openssl dsaparam 1024 -out dsa1024.pem
|
||||
$ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom
|
||||
2) enable ssh2:
|
||||
server: add 'Protocol 2,1' to /etc/sshd_config
|
||||
client: ssh -o 'Protocol 2,1', or add to .ssh/config
|
||||
|
||||
works:
|
||||
secsh-transport: works w/o rekey
|
||||
@ -11,11 +20,7 @@ works:
|
||||
tcp-forwarding: -L works
|
||||
dss: verification works,
|
||||
key database in ~/.ssh/known_hosts with bits == 0 hack
|
||||
dss: signature works, keygen w/ openssl:
|
||||
$ umask 077
|
||||
$ openssl dsaparam 1024 -out dsa1024.pem
|
||||
$ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom
|
||||
start sshd with '-2' flag
|
||||
dss: signature works, keygen w/ openssl
|
||||
client interops w/ sshd2, lshd
|
||||
server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT
|
||||
server supports multiple concurrent sessions (e.g. with SSH.com Windows client)
|
||||
@ -33,4 +38,4 @@ todo:
|
||||
sftp
|
||||
|
||||
-markus
|
||||
$Date: 2000/04/06 21:28:22 $
|
||||
$Date: 2000/04/12 07:45:43 $
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: channels.c,v 1.23 2000/04/12 08:45:06 damien Exp $");
|
||||
RCSID("$Id: channels.c,v 1.24 2000/04/12 10:17:38 damien Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
@ -437,6 +437,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
|
||||
if (ret == 1) {
|
||||
/* Start normal processing for the channel. */
|
||||
c->type = SSH_CHANNEL_OPEN;
|
||||
channel_pre_open_13(c, readset, writeset);
|
||||
} else if (ret == -1) {
|
||||
/*
|
||||
* We have received an X11 connection that has bad
|
||||
@ -460,6 +461,7 @@ channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset)
|
||||
int ret = x11_open_helper(c);
|
||||
if (ret == 1) {
|
||||
c->type = SSH_CHANNEL_OPEN;
|
||||
channel_pre_open_15(c, readset, writeset);
|
||||
} else if (ret == -1) {
|
||||
debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
|
||||
chan_read_failed(c);
|
||||
|
37
cipher.c
37
cipher.c
@ -12,11 +12,11 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $");
|
||||
RCSID("$Id: cipher.c,v 1.17 2000/04/12 10:17:39 damien Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "cipher.h"
|
||||
#include "config.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/md5.h>
|
||||
@ -26,7 +26,9 @@ RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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?
|
||||
*
|
||||
@ -81,7 +83,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
|
||||
@ -167,10 +169,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.
|
||||
@ -271,7 +297,6 @@ cipher_set_key(CipherContext *context, int cipher, const unsigned char *key,
|
||||
memset(padded, 0, sizeof(padded));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cipher_set_key_iv(CipherContext * context, int cipher,
|
||||
const unsigned char *key, int keylen,
|
||||
|
5
cipher.h
5
cipher.h
@ -11,7 +11,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: cipher.h,v 1.8 2000/04/06 02:32:39 damien Exp $"); */
|
||||
/* RCSID("$Id: cipher.h,v 1.9 2000/04/12 10:17:39 damien Exp $"); */
|
||||
|
||||
#ifndef CIPHER_H
|
||||
#define CIPHER_H
|
||||
@ -88,6 +88,9 @@ 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.
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: clientloop.c,v 1.9 2000/04/06 02:32:39 damien Exp $");
|
||||
RCSID("$Id: clientloop.c,v 1.10 2000/04/12 10:17:39 damien Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
@ -1013,7 +1013,7 @@ client_input_channel_req(int id, void *arg)
|
||||
rtype = packet_get_string(&len);
|
||||
reply = packet_get_char();
|
||||
|
||||
log("session_input_channel_req: rtype %s reply %d", rtype, reply);
|
||||
debug("session_input_channel_req: rtype %s reply %d", rtype, reply);
|
||||
|
||||
c = channel_lookup(id);
|
||||
if (c == NULL)
|
||||
|
33
compat.c
33
compat.c
@ -28,10 +28,12 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: compat.c,v 1.6 2000/04/12 08:45:06 damien Exp $");
|
||||
RCSID("$Id: compat.c,v 1.7 2000/04/12 10:17:39 damien Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "compat.h"
|
||||
|
||||
int compat13 = 0;
|
||||
int compat20 = 0;
|
||||
@ -65,9 +67,36 @@ compat_datafellows(const char *version)
|
||||
len = strlen(check[i]);
|
||||
if (strlen(version) >= len &&
|
||||
(strncmp(version, check[i], len) == 0)) {
|
||||
log("datafellows: %.200s", version);
|
||||
verbose("datafellows: %.200s", version);
|
||||
datafellows = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SEP ","
|
||||
int
|
||||
proto_spec(const char *spec)
|
||||
{
|
||||
char *s = xstrdup(spec);
|
||||
char *p;
|
||||
int ret = SSH_PROTO_UNKNOWN;
|
||||
|
||||
for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) {
|
||||
switch(atoi(p)) {
|
||||
case 1:
|
||||
if (ret == SSH_PROTO_UNKNOWN)
|
||||
ret |= SSH_PROTO_1_PREFERRED;
|
||||
ret |= SSH_PROTO_1;
|
||||
break;
|
||||
case 2:
|
||||
ret |= SSH_PROTO_2;
|
||||
break;
|
||||
default:
|
||||
log("ignoring bad proto spec: '%s'.", p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
xfree(s);
|
||||
return ret;
|
||||
}
|
||||
|
9
compat.h
9
compat.h
@ -26,13 +26,20 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* RCSID("$Id: compat.h,v 1.4 2000/04/04 04:39:01 damien Exp $"); */
|
||||
/* RCSID("$Id: compat.h,v 1.5 2000/04/12 10:17:39 damien Exp $"); */
|
||||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#define SSH_PROTO_UNKNOWN 0x00
|
||||
#define SSH_PROTO_1 0x01
|
||||
#define SSH_PROTO_1_PREFERRED 0x02
|
||||
#define SSH_PROTO_2 0x04
|
||||
|
||||
void enable_compat13(void);
|
||||
void enable_compat20(void);
|
||||
void compat_datafellows(const char *s);
|
||||
int proto_spec(const char *spec);
|
||||
extern int compat13;
|
||||
extern int compat20;
|
||||
extern int datafellows;
|
||||
|
24
dsa.c
24
dsa.c
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: dsa.c,v 1.1 2000/04/04 04:39:01 damien Exp $");
|
||||
RCSID("$Id: dsa.c,v 1.2 2000/04/12 06:37:02 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
@ -80,7 +80,7 @@ dsa_serverkey_from_blob(
|
||||
buffer_append(&b, serverhostkey, serverhostkeylen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp(KEX_DSS, ktype) != 0) {
|
||||
log("dsa_serverkey_from_blob: cannot handle type %s", ktype);
|
||||
error("dsa_serverkey_from_blob: cannot handle type %s", ktype);
|
||||
key_free(key);
|
||||
return NULL;
|
||||
}
|
||||
@ -90,10 +90,10 @@ dsa_serverkey_from_blob(
|
||||
buffer_get_bignum2(&b, dsa->pub_key);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0)
|
||||
log("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
|
||||
error("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
|
||||
buffer_free(&b);
|
||||
|
||||
log("keytype %s", ktype);
|
||||
debug("keytype %s", ktype);
|
||||
#ifdef DEBUG_DSS
|
||||
DSA_print_fp(stderr, dsa, 8);
|
||||
#endif
|
||||
@ -172,7 +172,7 @@ dsa_sign(
|
||||
Buffer b;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
log("dsa_sign: no DSA key");
|
||||
error("dsa_sign: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
digest = xmalloc(evp_md->md_size);
|
||||
@ -185,11 +185,11 @@ dsa_sign(
|
||||
rlen = BN_num_bytes(sig->r);
|
||||
slen = BN_num_bytes(sig->s);
|
||||
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
|
||||
log("bad sig size %d %d", rlen, slen);
|
||||
error("bad sig size %d %d", rlen, slen);
|
||||
DSA_SIG_free(sig);
|
||||
return -1;
|
||||
}
|
||||
log("sig size %d %d", rlen, slen);
|
||||
debug("sig size %d %d", rlen, slen);
|
||||
|
||||
memset(sigblob, 0, SIGBLOB_LEN);
|
||||
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
|
||||
@ -197,7 +197,7 @@ dsa_sign(
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
if (datafellows) {
|
||||
log("datafellows");
|
||||
debug("datafellows");
|
||||
ret = xmalloc(SIGBLOB_LEN);
|
||||
memcpy(ret, sigblob, SIGBLOB_LEN);
|
||||
if (lenp != NULL)
|
||||
@ -239,7 +239,7 @@ dsa_verify(
|
||||
int ret;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
log("dsa_verify: no DSA key");
|
||||
error("dsa_verify: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ dsa_verify(
|
||||
datafellows = 0;
|
||||
}
|
||||
|
||||
log("len %d datafellows %d", signaturelen, datafellows);
|
||||
debug("len %d datafellows %d", signaturelen, datafellows);
|
||||
|
||||
/* fetch signature */
|
||||
if (datafellows) {
|
||||
@ -262,7 +262,7 @@ dsa_verify(
|
||||
sigblob = (unsigned char *)buffer_get_string(&b, &len);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0)
|
||||
log("remaining bytes in signature %d", rlen);
|
||||
error("remaining bytes in signature %d", rlen);
|
||||
buffer_free(&b);
|
||||
}
|
||||
|
||||
@ -305,6 +305,6 @@ dsa_verify(
|
||||
txt = "error";
|
||||
break;
|
||||
}
|
||||
log("dsa_verify: signature %s", txt);
|
||||
debug("dsa_verify: signature %s", txt);
|
||||
return ret;
|
||||
}
|
||||
|
56
kex.c
56
kex.c
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $");
|
||||
RCSID("$Id: kex.c,v 1.3 2000/04/12 10:17:39 damien Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
@ -43,8 +43,6 @@ RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $");
|
||||
# include <openssl/dh.h>
|
||||
# include <openssl/crypto.h>
|
||||
# include <openssl/bio.h>
|
||||
# include <openssl/bn.h>
|
||||
# include <openssl/dh.h>
|
||||
# include <openssl/pem.h>
|
||||
#endif /* HAVE_OPENSSL */
|
||||
#if HAVE_SSL
|
||||
@ -52,12 +50,9 @@ RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $");
|
||||
# include <ssl/dh.h>
|
||||
# include <ssl/crypto.h>
|
||||
# include <ssl/bio.h>
|
||||
# include <ssl/bn.h>
|
||||
# include <ssl/dh.h>
|
||||
# include <ssl/pem.h>
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#include "entropy.h"
|
||||
#include "kex.h"
|
||||
|
||||
Buffer *
|
||||
@ -85,8 +80,36 @@ kex_init(char *myproposal[PROPOSAL_MAX])
|
||||
|
||||
/* diffie-hellman-group1-sha1 */
|
||||
|
||||
int
|
||||
dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
|
||||
{
|
||||
int i;
|
||||
int n = BN_num_bits(dh_pub);
|
||||
int bits_set = 0;
|
||||
|
||||
/* we only accept g==2 */
|
||||
if (!BN_is_word(dh->g, 2)) {
|
||||
log("invalid DH base != 2");
|
||||
return 0;
|
||||
}
|
||||
if (dh_pub->neg) {
|
||||
log("invalid public DH value: negativ");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i <= n; i++)
|
||||
if (BN_is_bit_set(dh_pub, i))
|
||||
bits_set++;
|
||||
debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
|
||||
|
||||
/* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
|
||||
if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
|
||||
return 1;
|
||||
log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DH *
|
||||
new_dh_group1()
|
||||
dh_new_group1()
|
||||
{
|
||||
static char *group1 =
|
||||
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
|
||||
@ -96,22 +119,23 @@ new_dh_group1()
|
||||
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
|
||||
"FFFFFFFF" "FFFFFFFF";
|
||||
DH *dh;
|
||||
int ret;
|
||||
int ret, tries = 0;
|
||||
dh = DH_new();
|
||||
if(dh == NULL)
|
||||
fatal("DH_new");
|
||||
ret = BN_hex2bn(&dh->p,group1);
|
||||
ret = BN_hex2bn(&dh->p, group1);
|
||||
if(ret<0)
|
||||
fatal("BN_hex2bn");
|
||||
dh->g = BN_new();
|
||||
if(dh->g == NULL)
|
||||
fatal("DH_new g");
|
||||
BN_set_word(dh->g,2);
|
||||
|
||||
seed_rng();
|
||||
if (DH_generate_key(dh) == 0)
|
||||
fatal("DH_generate_key");
|
||||
|
||||
BN_set_word(dh->g, 2);
|
||||
do {
|
||||
if (DH_generate_key(dh) == 0)
|
||||
fatal("DH_generate_key");
|
||||
if (tries++ > 10)
|
||||
fatal("dh_new_group1: too many bad keys: giving up");
|
||||
} while (!dh_pub_is_valid(dh, dh->pub_key));
|
||||
return dh;
|
||||
}
|
||||
|
||||
@ -356,7 +380,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
|
||||
choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]);
|
||||
choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]);
|
||||
choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]);
|
||||
log("kex: %s %s %s %s",
|
||||
debug("kex: %s %s %s %s",
|
||||
ctos ? "client->server" : "server->client",
|
||||
k->enc[mode].name,
|
||||
k->mac[mode].name,
|
||||
|
3
kex.h
3
kex.h
@ -102,7 +102,8 @@ struct Kex {
|
||||
};
|
||||
|
||||
Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
|
||||
DH *new_dh_group1();
|
||||
int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
|
||||
DH *dh_new_group1();
|
||||
Kex *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server);
|
||||
int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
|
||||
void bignum_print(BIGNUM *b);
|
||||
|
31
readconf.c
31
readconf.c
@ -14,13 +14,14 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: readconf.c,v 1.9 2000/04/01 01:09:25 damien Exp $");
|
||||
RCSID("$Id: readconf.c,v 1.10 2000/04/12 10:17:40 damien Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "cipher.h"
|
||||
#include "readconf.h"
|
||||
#include "match.h"
|
||||
#include "xmalloc.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* Format of the configuration file:
|
||||
|
||||
@ -103,7 +104,7 @@ typedef enum {
|
||||
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
|
||||
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
|
||||
oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
|
||||
oUsePrivilegedPort, oLogLevel
|
||||
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol
|
||||
} OpCodes;
|
||||
|
||||
/* Textual representations of the tokens. */
|
||||
@ -134,6 +135,8 @@ static struct {
|
||||
{ "proxycommand", oProxyCommand },
|
||||
{ "port", oPort },
|
||||
{ "cipher", oCipher },
|
||||
{ "ciphers", oCiphers },
|
||||
{ "protocol", oProtocol },
|
||||
{ "remoteforward", oRemoteForward },
|
||||
{ "localforward", oLocalForward },
|
||||
{ "user", oUser },
|
||||
@ -444,6 +447,26 @@ parse_int:
|
||||
*intptr = value;
|
||||
break;
|
||||
|
||||
case oCiphers:
|
||||
cp = strtok(NULL, WHITESPACE);
|
||||
if (!ciphers_valid(cp))
|
||||
fatal("%.200s line %d: Bad 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);
|
||||
@ -616,6 +639,8 @@ 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->hostname = NULL;
|
||||
options->proxy_command = NULL;
|
||||
@ -689,6 +714,8 @@ fill_default_options(Options * options)
|
||||
/* Selected in ssh_login(). */
|
||||
if (options->cipher == -1)
|
||||
options->cipher = SSH_CIPHER_NOT_SET;
|
||||
if (options->protocol == SSH_PROTO_UNKNOWN)
|
||||
options->protocol = SSH_PROTO_1;
|
||||
if (options->num_identity_files == 0) {
|
||||
options->identity_files[0] =
|
||||
xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: readconf.h,v 1.6 1999/12/06 00:47:29 damien Exp $"); */
|
||||
/* RCSID("$Id: readconf.h,v 1.7 2000/04/12 10:17:40 damien Exp $"); */
|
||||
|
||||
#ifndef READCONF_H
|
||||
#define READCONF_H
|
||||
@ -64,6 +64,8 @@ typedef struct {
|
||||
int number_of_password_prompts; /* Max number of password
|
||||
* prompts. */
|
||||
int cipher; /* Cipher to use. */
|
||||
char *ciphers; /* 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. */
|
||||
|
67
servconf.c
67
servconf.c
@ -12,11 +12,12 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: servconf.c,v 1.10 2000/04/12 08:45:06 damien Exp $");
|
||||
RCSID("$Id: servconf.c,v 1.11 2000/04/12 10:17:40 damien Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "servconf.h"
|
||||
#include "xmalloc.h"
|
||||
#include "compat.h"
|
||||
|
||||
/* add listen address */
|
||||
void add_listen_addr(ServerOptions *options, char *addr);
|
||||
@ -68,6 +69,8 @@ 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;
|
||||
}
|
||||
|
||||
void
|
||||
@ -139,6 +142,8 @@ 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;
|
||||
}
|
||||
|
||||
#define WHITESPACE " \t\r\n"
|
||||
@ -162,7 +167,7 @@ typedef enum {
|
||||
sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
|
||||
sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
|
||||
sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
|
||||
sIgnoreUserKnownHosts, sDSAKeyFile
|
||||
sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol
|
||||
} ServerOpCodes;
|
||||
|
||||
/* Textual representation of the tokens. */
|
||||
@ -211,6 +216,8 @@ static struct {
|
||||
{ "denyusers", sDenyUsers },
|
||||
{ "allowgroups", sAllowGroups },
|
||||
{ "denygroups", sDenyGroups },
|
||||
{ "ciphers", sCiphers },
|
||||
{ "protocol", sProtocol },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -494,7 +501,7 @@ parse_flag:
|
||||
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;
|
||||
@ -505,55 +512,67 @@ parse_flag:
|
||||
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;
|
||||
|
||||
case sAllowUsers:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_allow_users >= MAX_ALLOW_USERS) {
|
||||
fprintf(stderr, "%s line %d: too many allow users.\n",
|
||||
filename, linenum);
|
||||
exit(1);
|
||||
}
|
||||
if (options->num_allow_users >= MAX_ALLOW_USERS)
|
||||
fatal("%s 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) {
|
||||
fprintf(stderr, "%s line %d: too many deny users.\n",
|
||||
filename, linenum);
|
||||
exit(1);
|
||||
}
|
||||
if (options->num_deny_users >= MAX_DENY_USERS)
|
||||
fatal( "%s line %d: too many deny users.\n",
|
||||
filename, linenum);
|
||||
options->deny_users[options->num_deny_users++] = xstrdup(cp);
|
||||
}
|
||||
break;
|
||||
|
||||
case sAllowGroups:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_allow_groups >= MAX_ALLOW_GROUPS) {
|
||||
fprintf(stderr, "%s line %d: too many allow groups.\n",
|
||||
filename, linenum);
|
||||
exit(1);
|
||||
}
|
||||
if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
|
||||
fatal("%s line %d: too many allow groups.\n",
|
||||
filename, linenum);
|
||||
options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
|
||||
}
|
||||
break;
|
||||
|
||||
case sDenyGroups:
|
||||
while ((cp = strtok(NULL, WHITESPACE))) {
|
||||
if (options->num_deny_groups >= MAX_DENY_GROUPS) {
|
||||
fprintf(stderr, "%s line %d: too many deny groups.\n",
|
||||
filename, linenum);
|
||||
exit(1);
|
||||
}
|
||||
if (options->num_deny_groups >= MAX_DENY_GROUPS)
|
||||
fatal("%s 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 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;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
|
||||
filename, linenum, cp, opcode);
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: servconf.h,v 1.7 2000/04/12 08:45:07 damien Exp $"); */
|
||||
/* RCSID("$Id: servconf.h,v 1.8 2000/04/12 10:17:40 damien Exp $"); */
|
||||
|
||||
#ifndef SERVCONF_H
|
||||
#define SERVCONF_H
|
||||
@ -48,6 +48,8 @@ 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. */
|
||||
SyslogFacility log_facility; /* Facility for system logging. */
|
||||
LogLevel log_level; /* Level for system logging. */
|
||||
int rhosts_authentication; /* If true, permit rhosts
|
||||
|
9
ssh.c
9
ssh.c
@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: ssh.c,v 1.24 2000/04/06 02:32:40 damien Exp $");
|
||||
RCSID("$Id: ssh.c,v 1.25 2000/04/12 10:17:40 damien Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
@ -42,6 +42,7 @@ 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 */
|
||||
@ -336,8 +337,10 @@ main(int ac, char **av)
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
|
||||
SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
|
||||
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);
|
||||
|
14
ssh.h
14
ssh.h
@ -13,7 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* RCSID("$Id: ssh.h,v 1.30 2000/04/12 08:45:07 damien Exp $"); */
|
||||
/* RCSID("$Id: ssh.h,v 1.31 2000/04/12 10:17:41 damien Exp $"); */
|
||||
|
||||
#ifndef SSH_H
|
||||
#define SSH_H
|
||||
@ -54,14 +54,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
|
||||
|
89
sshconnect.c
89
sshconnect.c
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.61 2000/04/04 21:37:27 markus Exp $");
|
||||
RCSID("$OpenBSD: sshconnect.c,v 1.65 2000/04/12 07:56:16 markus Exp $");
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/bn.h>
|
||||
@ -993,7 +993,7 @@ void
|
||||
ssh_exchange_identification()
|
||||
{
|
||||
char buf[256], remote_version[256]; /* must be same size! */
|
||||
int remote_major, remote_minor, i;
|
||||
int remote_major, remote_minor, i, mismatch;
|
||||
int connection_in = packet_get_connection_in();
|
||||
int connection_out = packet_get_connection_out();
|
||||
|
||||
@ -1027,39 +1027,51 @@ ssh_exchange_identification()
|
||||
debug("Remote protocol version %d.%d, remote software version %.100s",
|
||||
remote_major, remote_minor, remote_version);
|
||||
|
||||
/*** XXX option for disabling 2.0 or 1.5 */
|
||||
compat_datafellows(remote_version);
|
||||
mismatch = 0;
|
||||
|
||||
/* Check if the remote protocol version is too old. */
|
||||
if (remote_major == 1 && remote_minor < 3)
|
||||
fatal("Remote machine has too old SSH software version.");
|
||||
|
||||
/* We speak 1.3, too. */
|
||||
if (remote_major == 1 && remote_minor == 3) {
|
||||
enable_compat13();
|
||||
if (options.forward_agent) {
|
||||
log("Agent forwarding disabled for protocol 1.3");
|
||||
options.forward_agent = 0;
|
||||
switch(remote_major) {
|
||||
case 1:
|
||||
if (remote_minor == 99 &&
|
||||
(options.protocol & SSH_PROTO_2) &&
|
||||
!(options.protocol & SSH_PROTO_1_PREFERRED)) {
|
||||
enable_compat20();
|
||||
break;
|
||||
}
|
||||
if (!(options.protocol & SSH_PROTO_1)) {
|
||||
mismatch = 1;
|
||||
break;
|
||||
}
|
||||
if (remote_minor < 3) {
|
||||
fatal("Remote machine has too old SSH software version.");
|
||||
} else if (remote_minor == 3) {
|
||||
/* We speak 1.3, too. */
|
||||
enable_compat13();
|
||||
if (options.forward_agent) {
|
||||
log("Agent forwarding disabled for protocol 1.3");
|
||||
options.forward_agent = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (options.protocol & SSH_PROTO_2) {
|
||||
enable_compat20();
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
mismatch = 1;
|
||||
break;
|
||||
}
|
||||
if ((remote_major == 2 && remote_minor == 0) ||
|
||||
(remote_major == 1 && remote_minor == 99)) {
|
||||
enable_compat20();
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* Removed for now, to permit compatibility with latter versions. The
|
||||
* server will reject our version and disconnect if it doesn't
|
||||
* support it.
|
||||
*/
|
||||
if (remote_major != PROTOCOL_MAJOR)
|
||||
if (mismatch)
|
||||
fatal("Protocol major versions differ: %d vs. %d",
|
||||
PROTOCOL_MAJOR, remote_major);
|
||||
#endif
|
||||
(options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||
remote_major);
|
||||
|
||||
/* Send our own protocol version identification. */
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
|
||||
compat20 ? 2 : PROTOCOL_MAJOR,
|
||||
compat20 ? 0 : PROTOCOL_MINOR,
|
||||
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
|
||||
compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1,
|
||||
SSH_VERSION);
|
||||
if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
|
||||
fatal("write: %.100s", strerror(errno));
|
||||
@ -1350,11 +1362,15 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
/* KEXINIT */
|
||||
|
||||
debug("Sending KEX init.");
|
||||
if (options.cipher == SSH_CIPHER_ARCFOUR ||
|
||||
if (options.ciphers != NULL) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
} else if (
|
||||
options.cipher == SSH_CIPHER_ARCFOUR ||
|
||||
options.cipher == SSH_CIPHER_3DES_CBC ||
|
||||
options.cipher == SSH_CIPHER_CAST128_CBC ||
|
||||
options.cipher == SSH_CIPHER_BLOWFISH_CBC) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = cipher_name(options.cipher);
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher);
|
||||
}
|
||||
if (options.compression) {
|
||||
@ -1404,7 +1420,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
debug("Sending SSH2_MSG_KEXDH_INIT.");
|
||||
|
||||
/* generate and send 'e', client DH public key */
|
||||
dh = new_dh_group1();
|
||||
dh = dh_new_group1();
|
||||
packet_start(SSH2_MSG_KEXDH_INIT);
|
||||
packet_put_bignum2(dh->pub_key);
|
||||
packet_send();
|
||||
@ -1451,6 +1467,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
/* signed H */
|
||||
signature = packet_get_string(&slen);
|
||||
|
||||
if (!dh_pub_is_valid(dh, dh_server_pub))
|
||||
packet_disconnect("bad server public DH value");
|
||||
|
||||
klen = DH_size(dh);
|
||||
kbuf = xmalloc(klen);
|
||||
kout = DH_compute_key(kbuf, dh_server_pub, dh);
|
||||
@ -1507,12 +1526,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
|
||||
packet_write_wait();
|
||||
debug("done: send SSH2_MSG_NEWKEYS.");
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
/* send 1st encrypted/maced/compressed message */
|
||||
packet_start(SSH2_MSG_IGNORE);
|
||||
packet_put_cstring("markus");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
#endif
|
||||
debug("done: KEX2.");
|
||||
}
|
||||
/*
|
||||
@ -1527,6 +1547,7 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
|
||||
unsigned int dlen;
|
||||
int partial;
|
||||
struct passwd *pw;
|
||||
char prompt[80];
|
||||
char *server_user, *local_user;
|
||||
char *auths;
|
||||
char *password;
|
||||
@ -1578,7 +1599,9 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
|
||||
fatal("passwd auth not supported: %s", auths);
|
||||
xfree(auths);
|
||||
/* try passwd */
|
||||
password = read_passphrase("password: ", 0);
|
||||
snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
|
||||
server_user, host);
|
||||
password = read_passphrase(prompt, 0);
|
||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||
packet_put_cstring(server_user);
|
||||
packet_put_cstring(service);
|
||||
|
80
sshd.c
80
sshd.c
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: sshd.c,v 1.99 2000/04/07 09:17:39 markus Exp $");
|
||||
RCSID("$OpenBSD: sshd.c,v 1.103 2000/04/12 08:11:36 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "rsa.h"
|
||||
@ -77,9 +77,6 @@ int IPv4or6 = AF_INET;
|
||||
int IPv4or6 = AF_UNSPEC;
|
||||
#endif
|
||||
|
||||
/* Flag indicating whether SSH2 is enabled */
|
||||
int allow_ssh2 = 0;
|
||||
|
||||
/*
|
||||
* Debug mode flag. This can be set on the command line. If debug
|
||||
* mode is enabled, extra debugging output will be sent to the system
|
||||
@ -284,16 +281,25 @@ chop(char *s)
|
||||
void
|
||||
sshd_exchange_identification(int sock_in, int sock_out)
|
||||
{
|
||||
int i;
|
||||
int i, mismatch;
|
||||
int remote_major, remote_minor;
|
||||
int major, minor;
|
||||
char *s;
|
||||
char buf[256]; /* Must not be larger than remote_version. */
|
||||
char remote_version[256]; /* Must be at least as big as buf. */
|
||||
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
|
||||
allow_ssh2 ? 1 : PROTOCOL_MAJOR,
|
||||
allow_ssh2 ? 99 : PROTOCOL_MINOR,
|
||||
SSH_VERSION);
|
||||
if ((options.protocol & SSH_PROTO_1) &&
|
||||
(options.protocol & SSH_PROTO_2)) {
|
||||
major = PROTOCOL_MAJOR_1;
|
||||
minor = 99;
|
||||
} else if (options.protocol & SSH_PROTO_2) {
|
||||
major = PROTOCOL_MAJOR_2;
|
||||
minor = PROTOCOL_MINOR_2;
|
||||
} else {
|
||||
major = PROTOCOL_MAJOR_1;
|
||||
minor = PROTOCOL_MINOR_1;
|
||||
}
|
||||
snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
|
||||
server_version_string = xstrdup(buf);
|
||||
|
||||
if (client_version_string == NULL) {
|
||||
@ -314,7 +320,6 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
buf[i] = '\n';
|
||||
buf[i + 1] = 0;
|
||||
continue;
|
||||
//break;
|
||||
}
|
||||
if (buf[i] == '\n') {
|
||||
/* buf[i] == '\n' */
|
||||
@ -345,8 +350,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
|
||||
compat_datafellows(remote_version);
|
||||
|
||||
mismatch = 0;
|
||||
switch(remote_major) {
|
||||
case 1:
|
||||
if (!(options.protocol & SSH_PROTO_1)) {
|
||||
mismatch = 1;
|
||||
break;
|
||||
}
|
||||
if (remote_minor < 3) {
|
||||
packet_disconnect("Your ssh version is too old and"
|
||||
"is no longer supported. Please install a newer version.");
|
||||
@ -354,27 +364,37 @@ sshd_exchange_identification(int sock_in, int sock_out)
|
||||
/* note that this disables agent-forwarding */
|
||||
enable_compat13();
|
||||
}
|
||||
if (remote_minor != 99)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
if (remote_minor == 99) {
|
||||
if (options.protocol & SSH_PROTO_2)
|
||||
enable_compat20();
|
||||
else
|
||||
mismatch = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (allow_ssh2) {
|
||||
if (options.protocol & SSH_PROTO_2) {
|
||||
enable_compat20();
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
s = "Protocol major versions differ.\n";
|
||||
(void) atomicio(write, sock_out, s, strlen(s));
|
||||
close(sock_in);
|
||||
close(sock_out);
|
||||
log("Protocol major versions differ for %s: %d vs. %d",
|
||||
get_remote_ipaddr(), PROTOCOL_MAJOR, remote_major);
|
||||
fatal_cleanup();
|
||||
mismatch = 1;
|
||||
break;
|
||||
}
|
||||
chop(server_version_string);
|
||||
chop(client_version_string);
|
||||
debug("Local version string %.200s", server_version_string);
|
||||
|
||||
if (mismatch) {
|
||||
s = "Protocol major versions differ.\n";
|
||||
(void) atomicio(write, sock_out, s, strlen(s));
|
||||
close(sock_in);
|
||||
close(sock_out);
|
||||
log("Protocol major versions differ for %s: %.200s vs. %.200s",
|
||||
get_remote_ipaddr(),
|
||||
server_version_string, client_version_string);
|
||||
fatal_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -410,11 +430,8 @@ main(int ac, char **av)
|
||||
initialize_server_options(&options);
|
||||
|
||||
/* Parse command-line arguments. */
|
||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ246")) != EOF) {
|
||||
while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) {
|
||||
switch (opt) {
|
||||
case '2':
|
||||
allow_ssh2 = 1;
|
||||
break;
|
||||
case '4':
|
||||
IPv4or6 = AF_INET;
|
||||
break;
|
||||
@ -593,6 +610,7 @@ main(int ac, char **av)
|
||||
public_key = RSA_new();
|
||||
sensitive_data.private_key = RSA_new();
|
||||
|
||||
/* XXX check options.protocol */
|
||||
log("Generating %d bit RSA key.", options.server_key_bits);
|
||||
rsa_generate_key(sensitive_data.private_key, public_key,
|
||||
options.server_key_bits);
|
||||
@ -1126,6 +1144,11 @@ do_ssh2_kex()
|
||||
|
||||
/* KEXINIT */
|
||||
|
||||
if (options.ciphers != NULL) {
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
|
||||
}
|
||||
|
||||
debug("Sending KEX init.");
|
||||
|
||||
for (i = 0; i < PROPOSAL_MAX; i++)
|
||||
@ -1185,7 +1208,7 @@ do_ssh2_kex()
|
||||
#endif
|
||||
|
||||
/* generate DH key */
|
||||
dh = new_dh_group1(); /* XXX depends on 'kex' */
|
||||
dh = dh_new_group1(); /* XXX depends on 'kex' */
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
fprintf(stderr, "\np= ");
|
||||
@ -1196,6 +1219,8 @@ do_ssh2_kex()
|
||||
bignum_print(dh->pub_key);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
if (!dh_pub_is_valid(dh, dh_client_pub))
|
||||
packet_disconnect("bad client public DH value");
|
||||
|
||||
klen = DH_size(dh);
|
||||
kbuf = xmalloc(klen);
|
||||
@ -1267,11 +1292,12 @@ do_ssh2_kex()
|
||||
packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
|
||||
debug("GOT SSH2_MSG_NEWKEYS.");
|
||||
|
||||
#ifdef DEBUG_KEXDH
|
||||
/* send 1st encrypted/maced/compressed message */
|
||||
packet_start(SSH2_MSG_IGNORE);
|
||||
packet_put_cstring("markus");
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
#endif
|
||||
debug("done: KEX2.");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user