Example #1
0
static void
conloop(void)
{
    struct timeval seltime, now;
    fd_set *r, *e;
    con *c;
    int i;

    gettimeofday(&now, NULL);
    c = TAILQ_FIRST(&tq);

    if (c && (c->c_tv.tv_sec > now.tv_sec ||
              (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) {
        seltime = c->c_tv;
        seltime.tv_sec -= now.tv_sec;
        seltime.tv_usec -= now.tv_usec;
        if (seltime.tv_usec < 0) {
            seltime.tv_usec += 1000000;
            seltime.tv_sec--;
        }
    } else
        timerclear(&seltime);

    r = xcalloc(read_wait_nfdset, sizeof(fd_mask));
    e = xcalloc(read_wait_nfdset, sizeof(fd_mask));
    memcpy(r, read_wait, read_wait_nfdset * sizeof(fd_mask));
    memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask));

    while (select(maxfd, r, NULL, e, &seltime) == -1 &&
            (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
        ;

    for (i = 0; i < maxfd; i++) {
        if (FD_ISSET(i, e)) {
            error("%s: exception!", fdcon[i].c_name);
            confree(i);
        } else if (FD_ISSET(i, r))
            conread(i);
    }
    free(r);
    free(e);

    c = TAILQ_FIRST(&tq);
    while (c && (c->c_tv.tv_sec < now.tv_sec ||
                 (c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) {
        int s = c->c_fd;

        c = TAILQ_NEXT(c, c_link);
        conrecycle(s);
    }
}
Example #2
0
static void
congreet(int s)
{
    int n = 0, remote_major = 0, remote_minor = 0;
    char buf[256], *cp;
    char remote_version[sizeof buf];
    size_t bufsiz;
    con *c = &fdcon[s];

    for (;;) {
        memset(buf, '\0', sizeof(buf));
        bufsiz = sizeof(buf);
        cp = buf;
        while (bufsiz-- &&
                (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') {
            if (*cp == '\r')
                *cp = '\n';
            cp++;
        }
        if (n != 1 || strncmp(buf, "SSH-", 4) == 0)
            break;
    }
    if (n == 0) {
        switch (errno) {
        case EPIPE:
            error("%s: Connection closed by remote host", c->c_name);
            break;
        case ECONNREFUSED:
            break;
        default:
            error("read (%s): %s", c->c_name, strerror(errno));
            break;
        }
        conrecycle(s);
        return;
    }
    if (*cp != '\n' && *cp != '\r') {
        error("%s: bad greeting", c->c_name);
        confree(s);
        return;
    }
    *cp = '\0';
    if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
               &remote_major, &remote_minor, remote_version) == 3)
        compat_datafellows(remote_version);
    else
        datafellows = 0;
    if (c->c_keytype != KT_RSA1) {
        if (!ssh2_capable(remote_major, remote_minor)) {
            debug("%s doesn't support ssh2", c->c_name);
            confree(s);
            return;
        }
    } else if (remote_major != 1) {
        debug("%s doesn't support ssh1", c->c_name);
        confree(s);
        return;
    }
    fprintf(stderr, "# %s %s\n", c->c_name, chop(buf));
    n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
                 c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
                 c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
    if (n < 0 || (size_t)n >= sizeof(buf)) {
        error("snprintf: buffer too small");
        confree(s);
        return;
    }
    if (atomicio(vwrite, s, buf, n) != (size_t)n) {
        error("write (%s): %s", c->c_name, strerror(errno));
        confree(s);
        return;
    }
    if (c->c_keytype != KT_RSA1) {
        keyprint(c, keygrab_ssh2(c));
        confree(s);
        return;
    }
    c->c_status = CS_SIZE;
    contouch(s);
}
Example #3
0
static void
congreet(int s)
{
	int n = 0, remote_major = 0, remote_minor = 0;
	char buf[256], *cp;
	char remote_version[sizeof buf];
	size_t bufsiz;
	con *c = &fdcon[s];

	/* send client banner */
	n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
	    PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
	if (n < 0 || (size_t)n >= sizeof(buf)) {
		error("snprintf: buffer too small");
		confree(s);
		return;
	}
	if (atomicio(vwrite, s, buf, n) != (size_t)n) {
		error("write (%s): %s", c->c_name, strerror(errno));
		confree(s);
		return;
	}

	for (;;) {
		memset(buf, '\0', sizeof(buf));
		bufsiz = sizeof(buf);
		cp = buf;
		while (bufsiz-- &&
		    (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') {
			if (*cp == '\r')
				*cp = '\n';
			cp++;
		}
		if (n != 1 || strncmp(buf, "SSH-", 4) == 0)
			break;
	}
	if (n == 0) {
		switch (errno) {
		case EPIPE:
			error("%s: Connection closed by remote host", c->c_name);
			break;
		case ECONNREFUSED:
			break;
		default:
			error("read (%s): %s", c->c_name, strerror(errno));
			break;
		}
		conrecycle(s);
		return;
	}
	if (*cp != '\n' && *cp != '\r') {
		error("%s: bad greeting", c->c_name);
		confree(s);
		return;
	}
	*cp = '\0';
	if ((c->c_ssh = ssh_packet_set_connection(NULL, s, s)) == NULL)
		fatal("ssh_packet_set_connection failed");
	ssh_packet_set_timeout(c->c_ssh, timeout, 1);
	ssh_set_app_data(c->c_ssh, c);	/* back link */
	if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
	    &remote_major, &remote_minor, remote_version) == 3)
		c->c_ssh->compat = compat_datafellows(remote_version);
	else
		c->c_ssh->compat = 0;
	if (!ssh2_capable(remote_major, remote_minor)) {
		debug("%s doesn't support ssh2", c->c_name);
		confree(s);
		return;
	}
	fprintf(stderr, "%c %s:%d %s\n", print_sshfp ? ';' : '#',
	    c->c_name, ssh_port, chop(buf));
	keygrab_ssh2(c);
	confree(s);
}