lshd.c 4.91 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1 2 3
/* lshd.c
 *
 * main server program.
4 5
 *
 * $Id$ */
Niels Möller's avatar
Niels Möller committed
6

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/* 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
25 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

33 34 35 36
#include "alist.h"
#include "atoms.h"
#include "crypto.h"
#include "format.h"
Niels Möller's avatar
Niels Möller committed
37
#include "io.h"
38
#include "randomness.h"
Niels Möller's avatar
Niels Möller committed
39
#include "server.h"
40 41 42 43 44 45 46 47
#include "server_keyexchange.h"
#include "werror.h"
#include "xalloc.h"

#if 0
#include "crypto.h"
#include "publickey_crypto.h"
#endif
Niels Möller's avatar
Niels Möller committed
48

Niels Möller's avatar
Niels Möller committed
49 50
#define BLOCK_SIZE 32768

Niels Möller's avatar
Niels Möller committed
51 52 53 54 55 56 57 58 59 60
/* Global variable */
struct io_backend backend;

void usage() NORETURN;

void usage()
{
  exit(1);
}

Niels Möller's avatar
Niels Möller committed
61 62 63 64
struct signer *secret_key;
struct lsh_string *public_key;

/* A key generated by gnupg */
65
static void init_host_key(struct randomness *r)
Niels Möller's avatar
Niels Möller committed
66 67 68
{
  mpz_t p, q, g, y, a;
  mpz_t tmp;
69
  struct lsh_string *s;
Niels Möller's avatar
Niels Möller committed
70 71 72 73 74 75 76
  
  mpz_init_set_str(p,
		   "BC7797D55CF2449CA4B02396246AF5C75CA38C52B6F2E543"
		   "6754198B137B25B0A81DFE269D5CDFD0AEA290A32BA5B918"
		   "B58D64762D40EAA8D70F282B3AC4A7771171B1B1D1AE89F4"
		   "1CD091FE95A6F42A2340081F9E97A4B5F953DE223F10F878"
		   "4C0619A9979643E5325DF71C9C088F3BC82FA0A6C47B5C64"
77
		   "BC07A31B9CDB2B07", 16);
Niels Möller's avatar
Niels Möller committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  mpz_init_set_str(q,
		   "867F7E6563B3FAF19B65C83E9B843150C5CC2201", 16);
  mpz_init_set_str(g,
		   "7FA83EAEDFD8679A4A80C869AD7E353F3B517569C2079C79"
		   "97EA6655764581B073F71AA15C07A789AEB213B106741AAB"
		   "CA81B8300B1F8510D3CD1C3D9D7D11640C1608E8E2E71527"
		   "68B8FDCB5544E29A020D14CC5C12E264C59E57E9F6832DA7"
		   "10B805CD9866C1110D60069D31D5A72D1A1ED96F2B11CFEF"
		   "7AB347F0632CB0C7", 16);
  mpz_init_set_str(y,
		   "2DA5B458DF3616097FA22DB6BDDD31A29E532054D4C208F7"
		   "EBF63EB2476E8E98E0885CFBC5669B56EC834E42058E8BCF"
		   "C259CA1BE981D7721306709499DE27E7B13F62359D9520D1"
		   "3D73C62E8E5C5F6B8E2C70217EC3B557FBCB98535BE3C6EE"
		   "0C71DEC1FE9C6791D3780DD8D593D5030969D303A5818B01"
		   "C4B855C07E8C4F64", 16);
  mpz_set_str(a,
	      "295190AEDBBD6EBD2F817F7D8CCC8B0095DCD82E", 16);

  mpz_init_set(tmp, g);
  mpz_powm(tmp, tmp, a, p);
  if (mpz_cmp(tmp, y))
    fatal("Test key invalid\n");

  mpz_clear(tmp);

  public_key = ssh_format("%a%n%n%n%n", ATOM_SSH_DSS, p, q, g, y);
  s = ssh_format("%n", a);

  secret_key = MAKE_SIGNER(make_dss_algorithm(r),
			   public_key->length, public_key->data,
			   s->length, s->data);

  lsh_free(s);
  mpz_clear(p);
  mpz_clear(q);
  mpz_clear(g);
  mpz_clear(y);
  mpz_clear(a);
}

Niels Möller's avatar
Niels Möller committed
119 120
int main(int argc, char **argv)
{
121
  char *host = NULL;  /* Interface to bind */
Niels Möller's avatar
Niels Möller committed
122 123 124
  char *port = "ssh";
  int option;

125
  struct sockaddr_in local;
126

Niels Möller's avatar
Niels Möller committed
127
  struct lsh_string *random_seed;
128 129 130 131
  struct randomness *r;
  struct diffie_hellman_method *dh;
  struct keyexchange_algorithm *kex;
  struct alist *algorithms;
Niels Möller's avatar
Niels Möller committed
132
  struct make_kexinit *make_kexinit;
133 134
  struct packet_handler *kexinit_handler;
  
Niels Möller's avatar
Niels Möller committed
135 136 137 138
  /* 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
139
  while((option = getopt(argc, argv, "dp:qi:v")) != -1)
Niels Möller's avatar
Niels Möller committed
140 141 142 143 144 145 146 147 148 149 150
    switch(option)
      {
      case 'p':
	port = optarg;
	break;
      case 'q':
	quiet_flag = 1;
	break;
      case 'd':
	debug_flag = 1;
	break;
151 152 153
      case 'i':
	host = optarg;
	break;
Niels Möller's avatar
Niels Möller committed
154 155 156
      case 'v':
	verbose_flag = 1;
	break;
Niels Möller's avatar
Niels Möller committed
157 158 159 160 161 162 163
      default:
	usage();
      }

  if ( (argc - optind) != 0)
    usage();

Niels Möller's avatar
Niels Möller committed
164 165 166
  random_seed = ssh_format("%z", "foobar");

  r = make_poor_random(&sha_algorithm, random_seed);
167 168 169 170 171 172 173 174
  dh = make_dh1(r);
  init_host_key(r); /* Initializes public_key and secret_key */
  kex = make_dh_server(dh, public_key, secret_key);
  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);
Niels Möller's avatar
Niels Möller committed
175 176 177
  make_kexinit = make_test_kexinit(r);
  kexinit_handler = make_kexinit_handler(CONNECTION_SERVER,
					 make_kexinit, algorithms);
178
    
179
  if (!get_inaddr(&local, host, port, "tcp"))
Niels Möller's avatar
Niels Möller committed
180 181 182 183 184
    {
      fprintf(stderr, "No such host or service");
      exit(1);
    }

Niels Möller's avatar
Niels Möller committed
185
  if (!io_listen(&backend, &local, 
Niels Möller's avatar
Niels Möller committed
186
	    make_server_callback(&backend,
187 188
				 "lsh - a free ssh",
				 BLOCK_SIZE,
Niels Möller's avatar
Niels Möller committed
189
				 r, make_kexinit,
190
				 kexinit_handler)))
Niels Möller's avatar
Niels Möller committed
191 192 193 194
    {
      werror("lsh: Connection failed: %s\n", strerror(errno));
      return 1;
    }
Niels Möller's avatar
Niels Möller committed
195
  
Niels Möller's avatar
Niels Möller committed
196
  io_run(&backend);
Niels Möller's avatar
Niels Möller committed
197 198 199

  return 0;
}