lshd.c 5.64 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
#include "alist.h"
#include "atoms.h"
35
#include "channel.h"
36
#include "charset.h"
37 38
#include "crypto.h"
#include "format.h"
Niels Möller's avatar
Niels Möller committed
39
#include "io.h"
Niels Möller's avatar
Niels Möller committed
40
#include "password.h"
41
#include "randomness.h"
Niels Möller's avatar
Niels Möller committed
42
#include "server.h"
43
#include "server_keyexchange.h"
Niels Möller's avatar
Niels Möller committed
44
#include "ssh.h"
Niels Möller's avatar
Niels Möller committed
45
#include "userauth.h"
46 47 48
#include "werror.h"
#include "xalloc.h"

49
/* Block size for stdout and stderr buffers */
Niels Möller's avatar
Niels Möller committed
50 51
#define BLOCK_SIZE 32768

Niels Möller's avatar
Niels Möller committed
52
void usage(void) NORETURN;
Niels Möller's avatar
Niels Möller committed
53

Niels Möller's avatar
Niels Möller committed
54
void usage(void)
Niels Möller's avatar
Niels Möller committed
55 56 57 58
{
  exit(1);
}

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

/* A key generated by gnupg */
63
static void init_host_key(struct randomness *r)
Niels Möller's avatar
Niels Möller committed
64 65 66
{
  mpz_t p, q, g, y, a;
  mpz_t tmp;
67
  struct lsh_string *s;
Niels Möller's avatar
Niels Möller committed
68 69 70 71 72 73 74
  
  mpz_init_set_str(p,
		   "BC7797D55CF2449CA4B02396246AF5C75CA38C52B6F2E543"
		   "6754198B137B25B0A81DFE269D5CDFD0AEA290A32BA5B918"
		   "B58D64762D40EAA8D70F282B3AC4A7771171B1B1D1AE89F4"
		   "1CD091FE95A6F42A2340081F9E97A4B5F953DE223F10F878"
		   "4C0619A9979643E5325DF71C9C088F3BC82FA0A6C47B5C64"
75
		   "BC07A31B9CDB2B07", 16);
Niels Möller's avatar
Niels Möller committed
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
  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);
92 93
  mpz_init_set_str(a,
		   "295190AEDBBD6EBD2F817F7D8CCC8B0095DCD82E", 16);
Niels Möller's avatar
Niels Möller committed
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

  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);

Niels Möller's avatar
Niels Möller committed
109 110 111
  if (!secret_key)
    fatal("Can't parse secret key\n");

112
  lsh_string_free(s);
Niels Möller's avatar
Niels Möller committed
113 114 115 116 117 118 119
  mpz_clear(p);
  mpz_clear(q);
  mpz_clear(g);
  mpz_clear(y);
  mpz_clear(a);
}

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

126
  struct sockaddr_in local;
127

128 129 130
  /* STATIC, because the object exists at gc time */
  struct io_backend backend = { STATIC_HEADER };

Niels Möller's avatar
Niels Möller committed
131
  struct lsh_string *random_seed;
132 133 134 135
  struct randomness *r;
  struct diffie_hellman_method *dh;
  struct keyexchange_algorithm *kex;
  struct alist *algorithms;
Niels Möller's avatar
Niels Möller committed
136
  struct make_kexinit *make_kexinit;
137 138
  struct packet_handler *kexinit_handler;
  
Niels Möller's avatar
Niels Möller committed
139 140 141
  /* For filtering messages. Could perhaps also be used when converting
   * strings to and from UTF8. */
  setlocale(LC_CTYPE, "");
142 143
  /* FIXME: Choose character set depending on the locale */
  set_local_charset(CHARSET_LATIN1);
Niels Möller's avatar
Niels Möller committed
144
  
Niels Möller's avatar
Niels Möller committed
145
  while((option = getopt(argc, argv, "dp:qi:v")) != -1)
Niels Möller's avatar
Niels Möller committed
146 147 148 149 150 151 152 153 154 155 156
    switch(option)
      {
      case 'p':
	port = optarg;
	break;
      case 'q':
	quiet_flag = 1;
	break;
      case 'd':
	debug_flag = 1;
	break;
157 158 159
      case 'i':
	host = optarg;
	break;
Niels Möller's avatar
Niels Möller committed
160 161 162
      case 'v':
	verbose_flag = 1;
	break;
Niels Möller's avatar
Niels Möller committed
163 164 165 166 167 168 169
      default:
	usage();
      }

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

170 171 172 173 174 175
  if (!get_inaddr(&local, host, port, "tcp"))
    {
      fprintf(stderr, "No such host or service");
      exit(1);
    }

176 177
  init_backend(&backend);
  
Niels Möller's avatar
Niels Möller committed
178 179 180
  random_seed = ssh_format("%z", "foobar");

  r = make_poor_random(&sha_algorithm, random_seed);
181 182 183 184 185 186 187 188
  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
189
  make_kexinit = make_test_kexinit(r);
190 191 192 193

  kexinit_handler = make_kexinit_handler
    (CONNECTION_SERVER,
     make_kexinit, algorithms,
Niels Möller's avatar
Niels Möller committed
194 195 196 197 198 199 200 201 202 203 204
     make_meta_service
     (make_alist
      (1, ATOM_SSH_USERAUTH,
       make_userauth_service
       (make_alist(1, ATOM_PASSWORD,
		   make_unix_userauth
		   (make_alist(1,
			       ATOM_SSH_CONNECTION,
			       make_server_session_service
			       (make_alist(0, -1),
				make_alist(1, ATOM_SHELL,
205 206 207 208 209
					   make_shell_handler(&backend),
					   -1)),
			       -1)),
		   -1)),
       -1)));
Niels Möller's avatar
Niels Möller committed
210
     
Niels Möller's avatar
Niels Möller committed
211
  if (!io_listen(&backend, &local, 
Niels Möller's avatar
Niels Möller committed
212
	    make_server_callback(&backend,
213
				 "lsh - a free ssh",
214
				 SSH_MAX_PACKET,
Niels Möller's avatar
Niels Möller committed
215
				 r, make_kexinit,
216
				 kexinit_handler)))
Niels Möller's avatar
Niels Möller committed
217 218 219 220
    {
      werror("lsh: Connection failed: %s\n", strerror(errno));
      return 1;
    }
Niels Möller's avatar
Niels Möller committed
221
  
Niels Möller's avatar
Niels Möller committed
222
  io_run(&backend);
Niels Möller's avatar
Niels Möller committed
223 224 225

  return 0;
}