summaryrefslogtreecommitdiff
path: root/crypto/openssh/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/sshconnect2.c')
-rw-r--r--crypto/openssh/sshconnect2.c451
1 files changed, 0 insertions, 451 deletions
diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c
deleted file mode 100644
index 0abcf89a0a073..0000000000000
--- a/crypto/openssh/sshconnect2.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Markus Friedl.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * 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.
- */
-
-#include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $");
-
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-#include <openssl/md5.h>
-#include <openssl/dh.h>
-#include <openssl/hmac.h>
-
-#include "ssh.h"
-#include "xmalloc.h"
-#include "rsa.h"
-#include "buffer.h"
-#include "packet.h"
-#include "cipher.h"
-#include "uidswap.h"
-#include "compat.h"
-#include "readconf.h"
-#include "bufaux.h"
-#include "ssh2.h"
-#include "kex.h"
-#include "myproposal.h"
-#include "key.h"
-#include "dsa.h"
-#include "sshconnect.h"
-#include "authfile.h"
-
-/* import */
-extern char *client_version_string;
-extern char *server_version_string;
-extern Options options;
-
-/*
- * SSH2 key exchange
- */
-
-unsigned char *session_id2 = NULL;
-int session_id2_len = 0;
-
-void
-ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
- Buffer *client_kexinit, Buffer *server_kexinit)
-{
- int i;
- int plen, dlen;
- unsigned int klen, kout;
- char *signature = NULL;
- unsigned int slen;
- char *server_host_key_blob = NULL;
- Key *server_host_key;
- unsigned int sbloblen;
- DH *dh;
- BIGNUM *dh_server_pub = 0;
- BIGNUM *shared_secret = 0;
- unsigned char *kbuf;
- unsigned char *hash;
-
- debug("Sending SSH2_MSG_KEXDH_INIT.");
- /* generate and send 'e', client DH public key */
- dh = dh_new_group1();
- packet_start(SSH2_MSG_KEXDH_INIT);
- packet_put_bignum2(dh->pub_key);
- packet_send();
- packet_write_wait();
-
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "\np= ");
- bignum_print(dh->p);
- fprintf(stderr, "\ng= ");
- bignum_print(dh->g);
- fprintf(stderr, "\npub= ");
- bignum_print(dh->pub_key);
- fprintf(stderr, "\n");
- DHparams_print_fp(stderr, dh);
-#endif
-
- debug("Wait SSH2_MSG_KEXDH_REPLY.");
-
- packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
-
- debug("Got SSH2_MSG_KEXDH_REPLY.");
-
- /* key, cert */
- server_host_key_blob = packet_get_string(&sbloblen);
- server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
- if (server_host_key == NULL)
- fatal("cannot decode server_host_key_blob");
-
- check_host_key(host, hostaddr, server_host_key,
- options.user_hostfile2, options.system_hostfile2);
-
- /* DH paramter f, server public DH key */
- dh_server_pub = BN_new();
- if (dh_server_pub == NULL)
- fatal("dh_server_pub == NULL");
- packet_get_bignum2(dh_server_pub, &dlen);
-
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "\ndh_server_pub= ");
- bignum_print(dh_server_pub);
- fprintf(stderr, "\n");
- debug("bits %d", BN_num_bits(dh_server_pub));
-#endif
-
- /* signed H */
- signature = packet_get_string(&slen);
- packet_done();
-
- 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);
-#ifdef DEBUG_KEXDH
- debug("shared secret: len %d/%d", klen, kout);
- fprintf(stderr, "shared secret == ");
- for (i = 0; i< kout; i++)
- fprintf(stderr, "%02x", (kbuf[i])&0xff);
- fprintf(stderr, "\n");
-#endif
- shared_secret = BN_new();
-
- BN_bin2bn(kbuf, kout, shared_secret);
- memset(kbuf, 0, klen);
- xfree(kbuf);
-
- /* calc and verify H */
- hash = kex_hash(
- client_version_string,
- server_version_string,
- buffer_ptr(client_kexinit), buffer_len(client_kexinit),
- buffer_ptr(server_kexinit), buffer_len(server_kexinit),
- server_host_key_blob, sbloblen,
- dh->pub_key,
- dh_server_pub,
- shared_secret
- );
- xfree(server_host_key_blob);
- DH_free(dh);
-#ifdef DEBUG_KEXDH
- fprintf(stderr, "hash == ");
- for (i = 0; i< 20; i++)
- fprintf(stderr, "%02x", (hash[i])&0xff);
- fprintf(stderr, "\n");
-#endif
- if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
- fatal("dsa_verify failed for server_host_key");
- key_free(server_host_key);
-
- kex_derive_keys(kex, hash, shared_secret);
- packet_set_kex(kex);
-
- /* save session id */
- session_id2_len = 20;
- session_id2 = xmalloc(session_id2_len);
- memcpy(session_id2, hash, session_id2_len);
-}
-
-void
-ssh_kex2(char *host, struct sockaddr *hostaddr)
-{
- int i, plen;
- Kex *kex;
- Buffer *client_kexinit, *server_kexinit;
- char *sprop[PROPOSAL_MAX];
-
- if (options.ciphers != NULL) {
- myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
- } else if (options.cipher == SSH_CIPHER_3DES) {
- myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- myproposal[PROPOSAL_ENC_ALGS_STOC] =
- (char *) cipher_name(SSH_CIPHER_3DES_CBC);
- } else if (options.cipher == SSH_CIPHER_BLOWFISH) {
- myproposal[PROPOSAL_ENC_ALGS_CTOS] =
- myproposal[PROPOSAL_ENC_ALGS_STOC] =
- (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
- }
- if (options.compression) {
- myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
- myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
- } else {
- myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
- myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
- }
-
- /* buffers with raw kexinit messages */
- server_kexinit = xmalloc(sizeof(*server_kexinit));
- buffer_init(server_kexinit);
- client_kexinit = kex_init(myproposal);
-
- /* algorithm negotiation */
- kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
- kex = kex_choose_conf(myproposal, sprop, 0);
- for (i = 0; i < PROPOSAL_MAX; i++)
- xfree(sprop[i]);
-
- /* server authentication and session key agreement */
- ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit);
-
- buffer_free(client_kexinit);
- buffer_free(server_kexinit);
- xfree(client_kexinit);
- xfree(server_kexinit);
-
- debug("Wait SSH2_MSG_NEWKEYS.");
- packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
- packet_done();
- debug("GOT SSH2_MSG_NEWKEYS.");
-
- debug("send SSH2_MSG_NEWKEYS.");
- packet_start(SSH2_MSG_NEWKEYS);
- packet_send();
- 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.");
-}
-
-/*
- * Authenticate user
- */
-int
-ssh2_try_passwd(const char *server_user, const char *host, const char *service)
-{
- static int attempt = 0;
- char prompt[80];
- char *password;
-
- if (attempt++ > options.number_of_password_prompts)
- return 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);
- packet_put_cstring("password");
- packet_put_char(0);
- packet_put_cstring(password);
- memset(password, 0, strlen(password));
- xfree(password);
- packet_send();
- packet_write_wait();
- return 1;
-}
-
-int
-ssh2_try_pubkey(char *filename,
- const char *server_user, const char *host, const char *service)
-{
- Buffer b;
- Key *k;
- unsigned char *blob, *signature;
- int bloblen, slen;
- struct stat st;
-
- if (stat(filename, &st) != 0) {
- debug("key does not exist: %s", filename);
- return 0;
- }
- debug("try pubkey: %s", filename);
-
- k = key_new(KEY_DSA);
- if (!load_private_key(filename, "", k, NULL)) {
- int success = 0;
- char *passphrase;
- char prompt[300];
- snprintf(prompt, sizeof prompt,
- "Enter passphrase for DSA key '%.100s': ",
- filename);
- passphrase = read_passphrase(prompt, 0);
- success = load_private_key(filename, passphrase, k, NULL);
- memset(passphrase, 0, strlen(passphrase));
- xfree(passphrase);
- if (!success)
- return 0;
- }
- dsa_make_key_blob(k, &blob, &bloblen);
-
- /* data to be signed */
- buffer_init(&b);
- buffer_append(&b, session_id2, session_id2_len);
- buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
- buffer_put_cstring(&b, server_user);
- buffer_put_cstring(&b,
- datafellows & SSH_BUG_PUBKEYAUTH ?
- "ssh-userauth" :
- service);
- buffer_put_cstring(&b, "publickey");
- buffer_put_char(&b, 1);
- buffer_put_cstring(&b, KEX_DSS);
- buffer_put_string(&b, blob, bloblen);
-
- /* generate signature */
- dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
- key_free(k);
-#ifdef DEBUG_DSS
- buffer_dump(&b);
-#endif
- if (datafellows & SSH_BUG_PUBKEYAUTH) {
- /* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */
- buffer_clear(&b);
- buffer_append(&b, session_id2, session_id2_len);
- buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
- buffer_put_cstring(&b, server_user);
- buffer_put_cstring(&b, service);
- buffer_put_cstring(&b, "publickey");
- buffer_put_char(&b, 1);
- buffer_put_cstring(&b, KEX_DSS);
- buffer_put_string(&b, blob, bloblen);
- }
- xfree(blob);
- /* append signature */
- buffer_put_string(&b, signature, slen);
- xfree(signature);
-
- /* skip session id and packet type */
- if (buffer_len(&b) < session_id2_len + 1)
- fatal("ssh2_try_pubkey: internal error");
- buffer_consume(&b, session_id2_len + 1);
-
- /* put remaining data from buffer into packet */
- packet_start(SSH2_MSG_USERAUTH_REQUEST);
- packet_put_raw(buffer_ptr(&b), buffer_len(&b));
- buffer_free(&b);
-
- /* send */
- packet_send();
- packet_write_wait();
- return 1;
-}
-
-void
-ssh_userauth2(const char *server_user, char *host)
-{
- int type;
- int plen;
- int sent;
- unsigned int dlen;
- int partial;
- int i = 0;
- char *auths;
- char *service = "ssh-connection"; /* service name */
-
- debug("send SSH2_MSG_SERVICE_REQUEST");
- packet_start(SSH2_MSG_SERVICE_REQUEST);
- packet_put_cstring("ssh-userauth");
- packet_send();
- packet_write_wait();
-
- type = packet_read(&plen);
- if (type != SSH2_MSG_SERVICE_ACCEPT) {
- fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
- }
- if (packet_remaining() > 0) {
- char *reply = packet_get_string(&plen);
- debug("service_accept: %s", reply);
- xfree(reply);
- } else {
- /* payload empty for ssh-2.0.13 ?? */
- debug("buggy server: service_accept w/o service");
- }
- packet_done();
- debug("got SSH2_MSG_SERVICE_ACCEPT");
-
- /* INITIAL request for auth */
- packet_start(SSH2_MSG_USERAUTH_REQUEST);
- packet_put_cstring(server_user);
- packet_put_cstring(service);
- packet_put_cstring("none");
- packet_send();
- packet_write_wait();
-
- for (;;) {
- sent = 0;
- type = packet_read(&plen);
- if (type == SSH2_MSG_USERAUTH_SUCCESS)
- break;
- if (type != SSH2_MSG_USERAUTH_FAILURE)
- fatal("access denied: %d", type);
- /* SSH2_MSG_USERAUTH_FAILURE means: try again */
- auths = packet_get_string(&dlen);
- debug("authentications that can continue: %s", auths);
- partial = packet_get_char();
- packet_done();
- if (partial)
- debug("partial success");
- if (options.dsa_authentication &&
- strstr(auths, "publickey") != NULL) {
- while (i < options.num_identity_files2) {
- sent = ssh2_try_pubkey(
- options.identity_files2[i++],
- server_user, host, service);
- if (sent)
- break;
- }
- }
- if (!sent) {
- if (options.password_authentication &&
- !options.batch_mode &&
- strstr(auths, "password") != NULL) {
- sent = ssh2_try_passwd(server_user, host, service);
- }
- }
- if (!sent)
- fatal("Permission denied (%s).", auths);
- xfree(auths);
- }
- packet_done();
- debug("ssh-userauth2 successfull");
-}