⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh-keyscan.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. * * Modification and redistribution in source and binary forms is * permitted provided that due credit is given to the author and the * OpenBSD project by leaving this copyright notice intact. */#include "includes.h"RCSID("$OpenBSD: ssh-keyscan.c,v 1.36 2002/06/16 21:30:58 itojun Exp $");#include "openbsd-compat/fake-queue.h"#include <openssl/bn.h>#include <setjmp.h>#include "xmalloc.h"#include "ssh.h"#include "ssh1.h"#include "key.h"#include "kex.h"#include "compat.h"#include "myproposal.h"#include "packet.h"#include "dispatch.h"#include "buffer.h"#include "bufaux.h"#include "log.h"#include "atomicio.h"#include "misc.h"/* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.   Default value is AF_UNSPEC means both IPv4 and IPv6. */#ifdef IPV4_DEFAULTint IPv4or6 = AF_INET;#elseint IPv4or6 = AF_UNSPEC;#endifint ssh_port = SSH_DEFAULT_PORT;#define KT_RSA1	1#define KT_DSA	2#define KT_RSA	4int get_keytypes = KT_RSA1;	/* Get only RSA1 keys by default */#define MAXMAXFD 256/* The number of seconds after which to give up on a TCP connection */int timeout = 5;int maxfd;#define MAXCON (maxfd - 10)#ifdef HAVE___PROGNAMEextern char *__progname;#elsechar *__progname;#endiffd_set *read_wait;size_t read_wait_size;int ncon;int nonfatal_fatal = 0;jmp_buf kexjmp;Key *kexjmp_key;/* * Keep a connection structure for each file descriptor.  The state * associated with file descriptor n is held in fdcon[n]. */typedef struct Connection {	u_char c_status;	/* State of connection on this file desc. */#define CS_UNUSED 0		/* File descriptor unused */#define CS_CON 1		/* Waiting to connect/read greeting */#define CS_SIZE 2		/* Waiting to read initial packet size */#define CS_KEYS 3		/* Waiting to read public key packet */	int c_fd;		/* Quick lookup: c->c_fd == c - fdcon */	int c_plen;		/* Packet length field for ssh packet */	int c_len;		/* Total bytes which must be read. */	int c_off;		/* Length of data read so far. */	int c_keytype;		/* Only one of KT_RSA1, KT_DSA, or KT_RSA */	char *c_namebase;	/* Address to free for c_name and c_namelist */	char *c_name;		/* Hostname of connection for errors */	char *c_namelist;	/* Pointer to other possible addresses */	char *c_output_name;	/* Hostname of connection for output */	char *c_data;		/* Data read from this fd */	Kex *c_kex;		/* The key-exchange struct for ssh2 */	struct timeval c_tv;	/* Time at which connection gets aborted */	TAILQ_ENTRY(Connection) c_link;	/* List of connections in timeout order. */} con;TAILQ_HEAD(conlist, Connection) tq;	/* Timeout Queue */con *fdcon;/* *  This is just a wrapper around fgets() to make it usable. *//* Stress-test.  Increase this later. */#define LINEBUF_SIZE 16typedef struct {	char *buf;	u_int size;	int lineno;	const char *filename;	FILE *stream;	void (*errfun) (const char *,...);} Linebuf;static Linebuf *Linebuf_alloc(const char *filename, void (*errfun) (const char *,...)){	Linebuf *lb;	if (!(lb = malloc(sizeof(*lb)))) {		if (errfun)			(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);		return (NULL);	}	if (filename) {		lb->filename = filename;		if (!(lb->stream = fopen(filename, "r"))) {			xfree(lb);			if (errfun)				(*errfun) ("%s: %s\n", filename, strerror(errno));			return (NULL);		}	} else {		lb->filename = "(stdin)";		lb->stream = stdin;	}	if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) {		if (errfun)			(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);		xfree(lb);		return (NULL);	}	lb->errfun = errfun;	lb->lineno = 0;	return (lb);}static voidLinebuf_free(Linebuf * lb){	fclose(lb->stream);	xfree(lb->buf);	xfree(lb);}#if 0static voidLinebuf_restart(Linebuf * lb){	clearerr(lb->stream);	rewind(lb->stream);	lb->lineno = 0;}static intLinebuf_lineno(Linebuf * lb){	return (lb->lineno);}#endifstatic char *Linebuf_getline(Linebuf * lb){	int n = 0;	lb->lineno++;	for (;;) {		/* Read a line */		if (!fgets(&lb->buf[n], lb->size - n, lb->stream)) {			if (ferror(lb->stream) && lb->errfun)				(*lb->errfun) ("%s: %s\n", lb->filename,				    strerror(errno));			return (NULL);		}		n = strlen(lb->buf);		/* Return it or an error if it fits */		if (n > 0 && lb->buf[n - 1] == '\n') {			lb->buf[n - 1] = '\0';			return (lb->buf);		}		if (n != lb->size - 1) {			if (lb->errfun)				(*lb->errfun) ("%s: skipping incomplete last line\n",				    lb->filename);			return (NULL);		}		/* Double the buffer if we need more space */		if (!(lb->buf = realloc(lb->buf, (lb->size *= 2)))) {			if (lb->errfun)				(*lb->errfun) ("linebuf (%s): realloc failed\n",				    lb->filename);			return (NULL);		}	}}static intfdlim_get(int hard){#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)	struct rlimit rlfd;	if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)		return (-1);	if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)		return 10000;	else		return hard ? rlfd.rlim_max : rlfd.rlim_cur;#elif defined (HAVE_SYSCONF)	return sysconf (_SC_OPEN_MAX);#else	return 10000;#endif}static intfdlim_set(int lim){#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)	struct rlimit rlfd;#endif	if (lim <= 0)		return (-1);#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)	if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)		return (-1);	rlfd.rlim_cur = lim;	if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0)		return (-1);#elif defined (HAVE_SETDTABLESIZE)	setdtablesize(lim);#endif	return (0);}/* * This is an strsep function that returns a null field for adjacent * separators.  This is the same as the 4.4BSD strsep, but different from the * one in the GNU libc. */static char *xstrsep(char **str, const char *delim){	char *s, *e;	if (!**str)		return (NULL);	s = *str;	e = s + strcspn(s, delim);	if (*e != '\0')		*e++ = '\0';	*str = e;	return (s);}/* * Get the next non-null token (like GNU strsep).  Strsep() will return a * null token for two adjacent separators, so we may have to loop. */static char *strnnsep(char **stringp, char *delim){	char *tok;	do {		tok = xstrsep(stringp, delim);	} while (tok && *tok == '\0');	return (tok);}static Key *keygrab_ssh1(con *c){	static Key *rsa;	static Buffer msg;	if (rsa == NULL) {		buffer_init(&msg);		rsa = key_new(KEY_RSA1);	}	buffer_append(&msg, c->c_data, c->c_plen);	buffer_consume(&msg, 8 - (c->c_plen & 7));	/* padding */	if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) {		error("%s: invalid packet type", c->c_name);		buffer_clear(&msg);		return NULL;	}	buffer_consume(&msg, 8);		/* cookie */	/* server key */	(void) buffer_get_int(&msg);	buffer_get_bignum(&msg, rsa->rsa->e);	buffer_get_bignum(&msg, rsa->rsa->n);	/* host key */	(void) buffer_get_int(&msg);	buffer_get_bignum(&msg, rsa->rsa->e);	buffer_get_bignum(&msg, rsa->rsa->n);	buffer_clear(&msg);	return (rsa);}static inthostjump(Key *hostkey){	kexjmp_key = hostkey;	longjmp(kexjmp, 1);}static intssh2_capable(int remote_major, int remote_minor){	switch (remote_major) {	case 1:		if (remote_minor == 99)			return 1;		break;	case 2:		return 1;	default:		break;	}	return 0;}static Key *keygrab_ssh2(con *c){	int j;	packet_set_connection(c->c_fd, c->c_fd);	enable_compat20();	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA?	    "ssh-dss": "ssh-rsa";	c->c_kex = kex_setup(myproposal);	c->c_kex->verify_host_key = hostjump;	if (!(j = setjmp(kexjmp))) {		nonfatal_fatal = 1;		dispatch_run(DISPATCH_BLOCK, &c->c_kex->done, c->c_kex);		fprintf(stderr, "Impossible! dispatch_run() returned!\n");		exit(1);	}	nonfatal_fatal = 0;	xfree(c->c_kex);	c->c_kex = NULL;	packet_close();	return j < 0? NULL : kexjmp_key;}static voidkeyprint(con *c, Key *key){	if (!key)		return;	fprintf(stdout, "%s ", c->c_output_name ? c->c_output_name : c->c_name);	key_write(key, stdout);	fputs("\n", stdout);}static inttcpconnect(char *host){	struct addrinfo hints, *ai, *aitop;	char strport[NI_MAXSERV];	int gaierr, s = -1;	snprintf(strport, sizeof strport, "%d", ssh_port);	memset(&hints, 0, sizeof(hints));	hints.ai_family = IPv4or6;	hints.ai_socktype = SOCK_STREAM;	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)		fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));	for (ai = aitop; ai; ai = ai->ai_next) {		s = socket(ai->ai_family, SOCK_STREAM, 0);		if (s < 0) {			error("socket: %s", strerror(errno));			continue;		}		if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)			fatal("F_SETFL: %s", strerror(errno));		if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0 &&		    errno != EINPROGRESS)			error("connect (`%s'): %s", host, strerror(errno));		else			break;		close(s);		s = -1;	}	freeaddrinfo(aitop);	return s;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -