lsh.c 3.74 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1 2 3
/* lsh.c
 *
 * client main program
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * $Id$ */

/* lsh, an implementation of the ssh protocol
 *
 * Copyright (C) 1998 Niels Mller
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Niels Möller's avatar
Niels Möller committed
24 25
 */

Niels Möller's avatar
Niels Möller committed
26
#include <errno.h>
Niels Möller's avatar
Niels Möller committed
27
#include <locale.h>
Niels Möller's avatar
Niels Möller committed
28 29
#include <stdio.h>
#include <string.h>
Niels Möller's avatar
Niels Möller committed
30 31

#include "getopt.h"
Niels Möller's avatar
Niels Möller committed
32

Niels Möller's avatar
Niels Möller committed
33 34
#include "alist.h"
#include "atoms.h"
Niels Möller's avatar
Niels Möller committed
35
#include "client.h"
Niels Möller's avatar
Niels Möller committed
36
#include "client_keyexchange.h"
Niels Möller's avatar
Niels Möller committed
37
#include "crypto.h"
Niels Möller's avatar
Niels Möller committed
38 39 40 41
#include "format.h"
#include "io.h"
#include "randomness.h"
#include "werror.h"
Niels Möller's avatar
Niels Möller committed
42
#include "xalloc.h"
Niels Möller's avatar
Niels Möller committed
43 44 45 46 47 48 49 50 51 52 53 54 55

#define BLOCK_SIZE 32768

/* Global variable */
struct io_backend backend;

void usage() NORETURN;

void usage()
{
  exit(1);
}

Niels Möller's avatar
Niels Möller committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
struct fake_host_db
{
  struct lookup_verifier super;

  struct signature_algorithm *algorithm;
};

static struct verifier *do_host_lookup(struct lookup_verifier *c,
				struct lsh_string *key)
{
  struct fake_host_db *closure = (struct fake_host_db *) c;
  
  return MAKE_VERIFIER(closure->algorithm, key->length, key->data);
}

static struct lookup_verifier *make_fake_host_db(struct signature_algorithm *a)
{
  struct fake_host_db *res = xalloc(sizeof(struct fake_host_db));

  res->super.lookup = do_host_lookup;
  res->algorithm = a;

  return &res->super;
}

Niels Möller's avatar
Niels Möller committed
81 82 83 84 85 86 87
int main(int argc, char **argv)
{
  char *host = NULL;
  char *port = "ssh";
  int option;

  struct sockaddr_in remote;
Niels Möller's avatar
Niels Möller committed
88

Niels Möller's avatar
Niels Möller committed
89 90 91 92 93 94 95 96 97
  struct lsh_string *random_seed;
  struct randomness *r;
  struct diffie_hellman_method *dh;
  struct keyexchange_algorithm *kex;
  struct alist *algorithms;
  struct make_kexinit *make_kexinit;
  struct packet_handler *kexinit_handler;
  struct lookup_verifier *lookup;
  
Niels Möller's avatar
Niels Möller committed
98 99 100
  /* For filtering messages. Could perhaps also be used when converting
   * strings to and from UTF8. */
  setlocale(LC_CTYPE, "");
Niels Möller's avatar
Niels Möller committed
101
  
Niels Möller's avatar
Niels Möller committed
102
  while((option = getopt(argc, argv, "dp:qv")) != -1)
Niels Möller's avatar
Niels Möller committed
103 104 105 106 107 108 109 110 111 112 113
    switch(option)
      {
      case 'p':
	port = optarg;
	break;
      case 'q':
	quiet_flag = 1;
	break;
      case 'd':
	debug_flag = 1;
	break;
Niels Möller's avatar
Niels Möller committed
114 115 116
      case 'v':
	verbose_flag = 1;
	break;
Niels Möller's avatar
Niels Möller committed
117 118 119 120 121 122 123 124 125
      default:
	usage();
      }

  if ( (argc - optind) < 1)
    usage();

  host = argv[optind];

Niels Möller's avatar
Niels Möller committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
  random_seed = ssh_format("%z", "gazonk");
  r = make_poor_random(&sha_algorithm, random_seed);
  dh = make_dh1(r);
  /* No randomness is needed for verifying signatures */
  lookup = make_fake_host_db(make_dss_algorithm(NULL)); 
  kex = make_dh_client(dh, lookup);
  algorithms = make_alist(4,
			  ATOM_ARCFOUR, crypto_rc4_algorithm,
			  ATOM_HMAC_SHA1, make_hmac_algorithm(&sha_algorithm),
			  ATOM_DIFFIE_HELLMAN_GROUP1_SHA1, kex,
			  ATOM_SSH_DSS, make_dss_algorithm(r), -1);
  make_kexinit = make_test_kexinit(r);
  kexinit_handler = make_kexinit_handler(CONNECTION_CLIENT,
					 make_kexinit, algorithms);

Niels Möller's avatar
Niels Möller committed
141 142
  if (!get_inaddr(&remote, host, port, "tcp"))
    {
Niels Möller's avatar
Niels Möller committed
143
      fprintf(stderr, "No such host or service\n");
Niels Möller's avatar
Niels Möller committed
144 145 146
      exit(1);
    }

Niels Möller's avatar
Niels Möller committed
147 148 149 150
  if (!io_connect(&backend, &remote, NULL,
		  make_client_callback(&backend,
				       "lsh - a free ssh",
				       BLOCK_SIZE,
Niels Möller's avatar
Niels Möller committed
151 152
				       r, make_kexinit,
				       kexinit_handler)))
Niels Möller's avatar
Niels Möller committed
153 154 155 156 157
    {
      werror("lsh: Connection failed: %s\n", strerror(errno));
      return 1;
    }
  
Niels Möller's avatar
Niels Möller committed
158
  lsh_string_free(random_seed);
Niels Möller's avatar
Niels Möller committed
159
  
Niels Möller's avatar
Niels Möller committed
160
  io_run(&backend);
Niels Möller's avatar
Niels Möller committed
161 162 163 164 165

  return 0;
}