Example #1
0
/* {{{ libssh2_publickey_response_success
 * Generic helper routine to wait for success response and nothing else
 */
static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
{
	LIBSSH2_SESSION *session = pkey->channel->session;
	unsigned char *data, *s;
	unsigned long data_len, response;

	while (1) {
		if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) {
			libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0);
			return -1;
		}

		s = data;
		if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) {
			libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0);
			LIBSSH2_FREE(session, data);
			return -1;
		}

		switch (response) {
			case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
			/* Error, or processing complete */
			{
				unsigned long status, descr_len, lang_len;
				unsigned char *descr, *lang;
				
				status = libssh2_ntohu32(s);					s += 4;
				descr_len = libssh2_ntohu32(s);					s += 4;
				descr = s;										s += descr_len;
				lang_len = libssh2_ntohu32(s);					s += 4;
				lang = s;										s += lang_len;

				if (s > data + data_len) {
					libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0);
					LIBSSH2_FREE(session, data);
					return -1;
				}

				if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
					LIBSSH2_FREE(session, data);
					return 0;
				}

				libssh2_publickey_status_error(pkey, session, status, descr, descr_len);
				LIBSSH2_FREE(session, data);
				return -1;
			}
			default:
				/* Unknown/Unexpected */
				libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0);
				LIBSSH2_FREE(session, data);
				data = NULL;
		}
	}
	/* never reached, but include `return` to silence compiler warnings */
	return -1;
}
Example #2
0
/*
 * _libssh2_packet_burn
 *
 * Loops _libssh2_transport_read() until any packet is available and promptly
 * discards it.
 * Used during KEX exchange to discard badly guessed KEX_INIT packets
 */
int
_libssh2_packet_burn(LIBSSH2_SESSION * session,
                     libssh2_nonblocking_states * state)
{
    unsigned char *data;
    size_t data_len;
    unsigned char i, all_packets[255];
    int ret;

    if (*state == libssh2_NB_state_idle) {
        for(i = 1; i < 255; i++) {
            all_packets[i - 1] = i;
        }
        all_packets[254] = 0;

        if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
                                 NULL, 0) == 0) {
            i = data[0];
            /* A packet was available in the packet brigade, burn it */
            LIBSSH2_FREE(session, data);
            return i;
        }

        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                       "Blocking until packet becomes available to burn");
        *state = libssh2_NB_state_created;
    }

    while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
        ret = _libssh2_transport_read(session);
        if (ret == LIBSSH2_ERROR_EAGAIN) {
            return ret;
        } else if (ret < 0) {
            *state = libssh2_NB_state_idle;
            return ret;
        } else if (ret == 0) {
            /* FIXME: this might busyloop */
            continue;
        }

        /* Be lazy, let packet_ask pull it out of the brigade */
        if (0 ==
            _libssh2_packet_ask(session, (unsigned char)ret,
                                         &data, &data_len, 0, NULL, 0)) {
            /* Smoke 'em if you got 'em */
            LIBSSH2_FREE(session, data);
            *state = libssh2_NB_state_idle;
            return ret;
        }
    }

    /* Only reached if the socket died */
    return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
Example #3
0
/* {{{ libssh2_packet_burn
 * Loops libssh2_packet_read() until any packet is available and promptly 
 * discards it
 * Used during KEX exchange to discard badly guessed KEX_INIT packets
 */
int
libssh2_packet_burn(LIBSSH2_SESSION * session,
                    libssh2_nonblocking_states * state)
{
    unsigned char *data;
    unsigned long data_len;
    unsigned char all_packets[255];
    int i;
    int ret;

    if (*state == libssh2_NB_state_idle) {
        for(i = 1; i < 256; i++) {
            all_packets[i - 1] = i;
        }

        if (libssh2_packet_askv_ex
            (session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
            i = data[0];
            /* A packet was available in the packet brigade, burn it */
            LIBSSH2_FREE(session, data);
            return i;
        }

        _libssh2_debug(session, LIBSSH2_DBG_TRANS,
                       "Blocking until packet becomes available to burn");
        *state = libssh2_NB_state_created;
    }

    while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
        if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
            return PACKET_EAGAIN;
        } else if (ret < 0) {
            *state = libssh2_NB_state_idle;
            return ret;
        } else if (ret == 0) {
            /* FIXME: this might busyloop */
            continue;
        }

        /* Be lazy, let packet_ask pull it out of the brigade */
        if (0 ==
            libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
                                  0)) {
            /* Smoke 'em if you got 'em */
            LIBSSH2_FREE(session, data);
            *state = libssh2_NB_state_idle;
            return ret;
        }
    }

    /* Only reached if the socket died */
    return -1;
}
Example #4
0
static void free_host(LIBSSH2_SESSION *session, struct known_host *entry)
{
    if(entry) {
        if(entry->key)
            LIBSSH2_FREE(session, entry->key);
        if(entry->salt)
            LIBSSH2_FREE(session, entry->salt);
        if(entry->name)
            LIBSSH2_FREE(session, entry->name);
        LIBSSH2_FREE(session, entry);
    }
}
Example #5
0
/* {{{ proto libssh2_userauth_list
 * List authentication methods
 * Will yield successful login if "none" happens to be allowable for this user
 * Not a common configuration for any SSH server though
 * username should be NULL, or a null terminated string
 */
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len)
{
	unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
	unsigned long data_len = username_len + 31; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" +
												   method_len(4) + method(4)"none" */
	unsigned long methods_len;
	unsigned char *data, *s;

	s = data = LIBSSH2_ALLOC(session, data_len);
	if (!data) {
		libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth_list", 0);
		return NULL;
	}

	*(s++) = SSH_MSG_USERAUTH_REQUEST;
	libssh2_htonu32(s, username_len);				s += 4;
	if (username) {
		memcpy(s, username, username_len);			s += username_len;
	}

	libssh2_htonu32(s, 14);							s += 4;
	memcpy(s, "ssh-connection", 14);				s += 14;

	libssh2_htonu32(s, 4);							s += 4;
	memcpy(s, "none", 4);							s += 4;

	if (libssh2_packet_write(session, data, data_len)) {
		libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-none request", 0);
		LIBSSH2_FREE(session, data);
		return NULL;
	}
	LIBSSH2_FREE(session, data);

	if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
		return NULL;
	}

	if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
		/* Wow, who'dve thought... */
		LIBSSH2_FREE(session, data);
		session->state |= LIBSSH2_STATE_AUTHENTICATED;
		return NULL;
	}

	methods_len = libssh2_ntohu32(data + 1);
	memcpy(data, data + 5, methods_len);
	data[methods_len] = '\0';
#ifdef LIBSSH2_DEBUG_USERAUTH
	_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", data);
#endif
	return (char *)data;
}
Example #6
0
static void
agent_free_identities(LIBSSH2_AGENT *agent) {
    struct agent_publickey *node;
    struct agent_publickey *next;

    for (node = _libssh2_list_first(&agent->head); node; node = next) {
        next = _libssh2_list_next(&node->node);
        LIBSSH2_FREE(agent->session, node->external.blob);
        LIBSSH2_FREE(agent->session, node->external.comment);
        LIBSSH2_FREE(agent->session, node);
    }
    _libssh2_list_init(&agent->head);
}
Example #7
0
/* {{{ libssh2_publickey_list_free
 * Free a previously fetched list of public keys
 */
LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list)
{
	LIBSSH2_SESSION *session = pkey->channel->session;
	libssh2_publickey_list *p = pkey_list;

	while (p->packet) {
		if (p->attrs) {
			LIBSSH2_FREE(session, p->attrs);
		}
		LIBSSH2_FREE(session, p->packet);
		p++;
	}

	LIBSSH2_FREE(session, pkey_list);
}
Example #8
0
static void
libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
{
    LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;

    LIBSSH2_FREE(session, address);
}
Example #9
0
/* {{{ libssh2_publickey_shutdown
 * Shutdown the publickey subsystem
 */
LIBSSH2_API void libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
{
	LIBSSH2_SESSION *session = pkey->channel->session;

	libssh2_channel_free(pkey->channel);
	LIBSSH2_FREE(session, pkey);
}
Example #10
0
/* {{{ libssh2_publickey_packet_receive
 * Read a packet from the subsystem
 */
static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, unsigned long *data_len)
{
	LIBSSH2_CHANNEL *channel = pkey->channel;
	LIBSSH2_SESSION *session = channel->session;
	unsigned char buffer[4];
	unsigned long packet_len;
	unsigned char *packet;

	if (libssh2_channel_read(channel, buffer, 4) != 4) {
		libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0);
		return -1;
	}

	packet_len = libssh2_ntohu32(buffer);
	packet = LIBSSH2_ALLOC(session, packet_len);
	if (!packet) {
		libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate publickey response buffer", 0);
		return -1;
	}

	if (libssh2_channel_read(channel, packet, packet_len) != packet_len) {
		libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0);
		LIBSSH2_FREE(session, packet);
		return -1;
	}

	*data = packet;
	*data_len = packet_len;

	return 0;
}
Example #11
0
/*
 * hostkey_method_ssh_dss_signv
 *
 * Construct a signature from an array of vectors
 */
static int
hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
                             unsigned char **signature,
                             size_t *signature_len,
                             int veccount,
                             const struct iovec datavec[],
                             void **abstract)
{
    libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
    unsigned char hash[SHA_DIGEST_LENGTH];
    libssh2_sha1_ctx ctx;
    int i;

    *signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
    if (!*signature) {
        return -1;
    }

    *signature_len = 2 * SHA_DIGEST_LENGTH;

    libssh2_sha1_init(&ctx);
    for(i = 0; i < veccount; i++) {
        libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
    }
    libssh2_sha1_final(ctx, hash);

    if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
        LIBSSH2_FREE(session, *signature);
        return -1;
    }

    return 0;
}
Example #12
0
/* {{{ libssh2_comp_method_zlib_init
 * All your bandwidth are belong to us (so save some)
 */
static int
libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
                              void **abstract)
{
    z_stream *strm;
    int status;

    strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
    if (!strm) {
        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                      "Unable to allocate memory for zlib compression/decompression",
                      0);
        return -1;
    }
    memset(strm, 0, sizeof(z_stream));

    strm->opaque = (voidpf) session;
    strm->zalloc = (alloc_func) libssh2_comp_method_zlib_alloc;
    strm->zfree = (free_func) libssh2_comp_method_zlib_free;
    if (compress) {
        /* deflate */
        status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
    } else {
        /* inflate */
        status = inflateInit(strm);
    }

    if (status != Z_OK) {
        LIBSSH2_FREE(session, strm);
        return -1;
    }
    *abstract = strm;

    return 0;
}
Example #13
0
/* {{{ libssh2_banner_set
 * Set the local banner
 */
LIBSSH2_API int
libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
{
    int banner_len = banner ? strlen(banner) : 0;

    if (session->local.banner) {
        LIBSSH2_FREE(session, session->local.banner);
        session->local.banner = NULL;
    }

    if (!banner_len) {
        return 0;
    }

    session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
    if (!session->local.banner) {
        libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                      "Unable to allocate memory for local banner", 0);
        return -1;
    }

    memcpy(session->local.banner, banner, banner_len);
    session->local.banner[banner_len] = '\0';
    _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s",
                   session->local.banner);
    session->local.banner[banner_len++] = '\r';
    session->local.banner[banner_len++] = '\n';
    session->local.banner[banner_len++] = '\0';

    return 0;
}
Example #14
0
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
                       libssh2_rsa_ctx * rsactx,
                       const unsigned char *hash,
                       unsigned long hash_len,
                       unsigned char **signature, unsigned long *signature_len)
{
    int ret;
    unsigned char *sig;
    unsigned int sig_len;

    sig_len = RSA_size(rsactx);
    sig = LIBSSH2_ALLOC(session, sig_len);

    if (!sig) {
        return -1;
    }

    ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);

    if (!ret) {
        LIBSSH2_FREE(session, sig);
        return -1;
    }

    *signature = sig;
    *signature_len = sig_len;

    return 0;
}
Example #15
0
/*
 * _libssh2_packet_ask
 *
 * Scan the brigade for a matching packet type, optionally poll the socket for
 * a packet first
 */
int
_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
                    unsigned char **data, size_t *data_len,
                    int match_ofs, const unsigned char *match_buf,
                    size_t match_len)
{
    LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);

    _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                   "Looking for packet of type: %d", (int) packet_type);

    while (packet) {
        if (packet->data[0] == packet_type
            && (packet->data_len >= (match_ofs + match_len))
            && (!match_buf ||
                (memcmp(packet->data + match_ofs, match_buf,
                        match_len) == 0))) {
            *data = packet->data;
            *data_len = packet->data_len;

            /* unlink struct from session->packets */
            _libssh2_list_remove(&packet->node);

            LIBSSH2_FREE(session, packet);

            return 0;
        }
        packet = _libssh2_list_next(&packet->node);
    }
    return -1;
}
Example #16
0
static libssh2pack_t
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
        unsigned char *dest, int len)
{
    struct transportpacket *p = &session->packet;
    int blocksize = session->remote.crypt->blocksize;

    /* if we get called with a len that isn't an even number of blocksizes
       we risk losing those extra bytes */
    assert((len % blocksize) == 0);

    while (len >= blocksize) {
        if (session->remote.crypt->crypt(session, source,
                                         &session->remote.crypt_abstract)) {
            libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
                          (char *) "Error decrypting packet", 0);
            LIBSSH2_FREE(session, p->payload);
            return PACKET_FAIL;
        }

        /* if the crypt() function would write to a given address it
           wouldn't have to memcpy() and we could avoid this memcpy()
           too */
        memcpy(dest, source, blocksize);

        len -= blocksize;       /* less bytes left */
        dest += blocksize;      /* advance write pointer */
        source += blocksize;    /* advance read pointer */
    }
    return PACKET_NONE;         /* all is fine */
}
Example #17
0
/* {{{ libssh2_packet_ask
 * Scan the brigade for a matching packet type, optionally poll the socket for
 * a packet first
 */
int
libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
                      unsigned char **data, unsigned long *data_len,
                      unsigned long match_ofs, const unsigned char *match_buf,
                      unsigned long match_len, int poll_socket)
{
    LIBSSH2_PACKET *packet = session->packets.head;

    if (poll_socket) {
        /*
         * XXX CHECK ***
         * When "poll_socket" is "1" libhss2_packet_read() can return
         * PACKET_EAGAIN.  I am not sure what should happen, but internally
         * there is only one location that might do so, libssh2_packet_askv_ex()
         */
        libssh2pack_t rc = libssh2_packet_read(session);
        if ((rc < 0) && !packet) {
            return rc;
        }
    }
    _libssh2_debug(session, LIBSSH2_DBG_TRANS,
                   "Looking for packet of type: %d", (int) packet_type);

    while (packet) {
        if (packet->data[0] == packet_type
            && (packet->data_len >= (match_ofs + match_len)) && (!match_buf
                                                                 ||
                                                                 (memcmp
                                                                  (packet->
                                                                   data +
                                                                   match_ofs,
                                                                   match_buf,
                                                                   match_len)
                                                                  == 0))) {
            *data = packet->data;
            *data_len = packet->data_len;

            if (packet->prev) {
                packet->prev->next = packet->next;
            } else {
                session->packets.head = packet->next;
            }

            if (packet->next) {
                packet->next->prev = packet->prev;
            } else {
                session->packets.tail = packet->prev;
            }

            LIBSSH2_FREE(session, packet);

            return 0;
        }
        packet = packet->next;
    }
    return -1;
}
Example #18
0
/* {{{ libssh2_mac_method_common_dtor
 * Cleanup simple mac methods
 */
static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstract)
{
	if (*abstract) {
		LIBSSH2_FREE(session, *abstract);
	}
	*abstract = NULL;

	return 0;
}
Example #19
0
/*
 * libssh2_agent_free()
 *
 * Free an ssh-agent handle.  This function also frees the internal
 * collection of public keys.
 */
LIBSSH2_API void
libssh2_agent_free(LIBSSH2_AGENT *agent) {
    /* Allow connection freeing when the socket has lost its connection */
    if (agent->fd != INVALID_SOCKET) {
        libssh2_agent_disconnect(agent);
    }
    agent_free_identities(agent);
    LIBSSH2_FREE(agent->session, agent);
}
Example #20
0
/* {{{ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange
 * Diffie-Hellman Group Exchange Key Exchange using SHA1
 * Negotiates random(ish) group for secret derivation
 */
static int libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSION *session)
{
	unsigned char request[13], *s, *data;
	unsigned long data_len, p_len, g_len, request_len;
	_libssh2_bn *p = _libssh2_bn_init ();
	_libssh2_bn *g = _libssh2_bn_init ();
	int ret;

	/* Ask for a P and G pair */
#ifdef LIBSSH2_DH_GEX_NEW
	request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
	libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_MINGROUP);
	libssh2_htonu32(request + 5, LIBSSH2_DH_GEX_OPTGROUP);
	libssh2_htonu32(request	+ 9, LIBSSH2_DH_GEX_MAXGROUP);
	request_len = 13;
#ifdef LIBSSH2_DEBUG_KEX
	_libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (New Method)");
#endif
#else
	request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
	libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_OPTGROUP);
	request_len = 5;
#ifdef LIBSSH2_DEBUG_KEX
	_libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (Old Method)");
#endif
#endif

	if (libssh2_packet_write(session, request, request_len)) {
		libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send Group Exchange Request", 0);
		ret = -1;
		goto dh_gex_clean_exit;
	}	

	if (libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, &data, &data_len)) {
		libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timeout waiting for GEX_GROUP reply", 0);
		ret = -1;
		goto dh_gex_clean_exit;
	}

	s = data + 1;
	p_len = libssh2_ntohu32(s);						s += 4;
	_libssh2_bn_from_bin(p, p_len, s);					s += p_len;

	g_len = libssh2_ntohu32(s);						s += 4;
	_libssh2_bn_from_bin(g, g_len, s);					s += g_len;

	ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, p_len, SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, data + 1, data_len - 1);

	LIBSSH2_FREE(session, data);

 dh_gex_clean_exit:
	_libssh2_bn_free(g);
	_libssh2_bn_free(p);

	return ret;
}
Example #21
0
/* {{{ libssh2_publickey_remove_ex
 * Remove an existing publickey so that authentication can no longer be performed using it
 */
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
                                                            const unsigned char *blob, unsigned long blob_len)
{
	LIBSSH2_CHANNEL *channel = pkey->channel;
	LIBSSH2_SESSION *session = channel->session;
	unsigned char *s, *packet = NULL;
	unsigned long packet_len = 22 + name_len + blob_len;
	/*	packet_len(4) + 
		remove_len(4) +
		"remove"(6) +
		name_len(4) +
		{name}
		blob_len(4) +
		{blob} */

	packet = LIBSSH2_ALLOC(session, packet_len);
	if (!packet) {
		libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"remove\" packet", 0);
		return -1;
	}

	s = packet;
	libssh2_htonu32(s, packet_len - 4);							s += 4;
	libssh2_htonu32(s, sizeof("remove") - 1);					s += 4;
	memcpy(s, "remove", sizeof("remove") - 1);					s += sizeof("remove") - 1;
	libssh2_htonu32(s, name_len);								s += 4;
	memcpy(s, name, name_len);									s += name_len;
	libssh2_htonu32(s, blob_len);								s += 4;
	memcpy(s, blob, blob_len);									s += blob_len;

#ifdef LIBSSH2_DEBUG_PUBLICKEY
	_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len);
#endif
    if ((s - packet) != libssh2_channel_write(channel, packet, (s - packet))) {
        libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0);
		LIBSSH2_FREE(session, packet);
		return -1;
    }
	LIBSSH2_FREE(session, packet);
	packet = NULL;

	return libssh2_publickey_response_success(pkey);
}
Example #22
0
static int
_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract)
{
    struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
    if (cctx && *cctx) {
        _libssh2_cipher_dtor(&(*cctx)->h);
        LIBSSH2_FREE(session, *cctx);
        *abstract = NULL;
    }
    return 0;
}
Example #23
0
static int
gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
                           unsigned char **method,
                           size_t *method_len,
                           unsigned char **pubkeydata,
                           size_t *pubkeydata_len,
                           EVP_PKEY *pk)
{
    DSA*           dsa = NULL;
    unsigned char* key;
    unsigned char* method_buf = NULL;
    size_t  key_len;

    _libssh2_debug(session,
                   LIBSSH2_TRACE_AUTH,
                   "Computing public key from DSA private key envelop");

    dsa = EVP_PKEY_get1_DSA(pk);
    if (dsa == NULL) {
        /* Assume memory allocation error... what else could it be ? */
        goto __alloc_error;
    }

    method_buf = LIBSSH2_ALLOC(session, 7);  /* ssh-dss. */
    if (method_buf == NULL) {
        goto __alloc_error;
    }

    key = gen_publickey_from_dsa(session, dsa, &key_len);
    if (key == NULL) {
        goto __alloc_error;
    }
    DSA_free(dsa);

    memcpy(method_buf, "ssh-dss", 7);
    *method         = method_buf;
    *method_len     = 7;
    *pubkeydata     = key;
    *pubkeydata_len = key_len;
    return 0;

  __alloc_error:
    if (dsa != NULL) {
        DSA_free(dsa);
    }
    if (method_buf != NULL) {
        LIBSSH2_FREE(session, method_buf);
    }

    _libssh2_error(session,
                   LIBSSH2_ERROR_ALLOC,
                   "Unable to allocate memory for private key data");
    return -1;
}
Example #24
0
/*
 * libssh2_knownhost_free
 *
 * Free an entire collection of known hosts.
 *
 */
LIBSSH2_API void
libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
{
    struct known_host *node;
    struct known_host *next;

    for(node = _libssh2_list_first(&hosts->head); node; node = next) {
        next = _libssh2_list_next(&node->node);
        free_host(hosts->session, node);
    }
    LIBSSH2_FREE(hosts->session, hosts);
}
Example #25
0
LIBSSH2_API void
libssh2_release_string_cache(LIBSSH2_SESSION *session,
                             libssh2_string_cache **cache)
{
    libssh2_string_cache *p;

    if (session && cache)
        while ((p = *cache)) {
            *cache = p->next;
            LIBSSH2_FREE(session, (char *) p);
        }
}
Example #26
0
static libssh2pack_t
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
              unsigned long data_len, ssize_t * ret)
{
    ssize_t rc;
    ssize_t length;
    struct transportpacket *p = &session->packet;

    if (!p->outbuf) {
        *ret = 0;
        return PACKET_NONE;
    }

    /* send as much as possible of the existing packet */
    if ((data != p->odata) || (data_len != p->olen)) {
        /* When we are about to complete the sending of a packet, it is vital
           that the caller doesn't try to send a new/different packet since
           we don't add this one up until the previous one has been sent. To
           make the caller really notice his/hers flaw, we return error for
           this case */
        return PACKET_BADUSE;
    }

    *ret = 1;                   /* set to make our parent return */

    /* number of bytes left to send */
    length = p->ototal_num - p->osent;

    rc = send(session->socket_fd, &p->outbuf[p->osent], length,
              LIBSSH2_SOCKET_SEND_FLAGS(session));

    if (rc == length) {
        /* the remainder of the package was sent */
        LIBSSH2_FREE(session, p->outbuf);
        p->outbuf = NULL;
        p->ototal_num = 0;
    } else if (rc < 0) {
        /* nothing was sent */
        if (errno != EAGAIN) {
            /* send failure! */
            return PACKET_FAIL;
        }
        return PACKET_EAGAIN;
    }

    debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
              length);
    p->osent += length;         /* we sent away this much data */

    return PACKET_NONE;
}
Example #27
0
/* {{{ libssh2_packet_burn
 * Loops libssh2_packet_read() until any packet is available and promptly discards it
 * Used during KEX exchange to discard badly guessed KEX_INIT packets
 */
int libssh2_packet_burn(LIBSSH2_SESSION *session)
{
	unsigned char *data;
	unsigned long data_len;
	char all_packets[255];
	int i;
	for(i = 1; i < 256; i++) all_packets[i - 1] = i;

	if (libssh2_packet_askv_ex(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
		i = data[0];
		/* A packet was available in the packet brigade, burn it */
		LIBSSH2_FREE(session, data);
		return i;
	}

#ifdef LIBSSH2_DEBUG_TRANSPORT
	_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Blocking until packet becomes available to burn");
#endif
	while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
		int ret = libssh2_packet_read(session, 1);
		if (ret < 0) {
			return -1;
		}
		if (ret == 0) continue;

		/* Be lazy, let packet_ask pull it out of the brigade */
		if (0 == libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0, 0)) {
			/* Smoke 'em if you got 'em */
			LIBSSH2_FREE(session, data);
			return ret;
		}
	}

	/* Only reached if the socket died */
	return -1;
}
Example #28
0
int
_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
                              libssh2_rsa_ctx *rsa,
                              const unsigned char *hash,
                              size_t hash_len,
                              unsigned char **signature,
                              size_t *signature_len)
{
    BCRYPT_PKCS1_PADDING_INFO paddingInfo;
    unsigned char *data, *sig;
    unsigned long cbData, datalen, siglen;
    int ret;

    datalen = (unsigned long)hash_len;
    data = malloc(datalen);
    if (!data) {
        return -1;
    }

    paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;

    memcpy(data, hash, datalen);

    ret = BCryptSignHash(rsa->hKey, &paddingInfo,
                         data, datalen, NULL, 0,
                         &cbData, BCRYPT_PAD_PKCS1);
    if (BCRYPT_SUCCESS(ret)) {
        siglen = cbData;
        sig = LIBSSH2_ALLOC(session, siglen);
        if (sig) {
            ret = BCryptSignHash(rsa->hKey, &paddingInfo,
                                 data, datalen, sig, siglen,
                                 &cbData, BCRYPT_PAD_PKCS1);
            if (BCRYPT_SUCCESS(ret)) {
                *signature_len = siglen;
                *signature = sig;
            } else {
                LIBSSH2_FREE(session, sig);
            }
        } else
            ret = STATUS_NO_MEMORY;
    }

    free(data);

    return BCRYPT_SUCCESS(ret) ? 0 : -1;
}
Example #29
0
/*
 * _libssh2_packet_ask
 *
 * Scan the brigade for a matching packet type, optionally poll the socket for
 * a packet first
 */
int
_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
                    unsigned char **data, unsigned long *data_len,
                    unsigned long match_ofs, const unsigned char *match_buf,
                    unsigned long match_len)
{
    LIBSSH2_PACKET *packet = session->packets.head;

    _libssh2_debug(session, LIBSSH2_DBG_TRANS,
                   "Looking for packet of type: %d", (int) packet_type);

    while (packet) {
        if (packet->data[0] == packet_type
            && (packet->data_len >= (match_ofs + match_len))
            && (!match_buf ||
                (memcmp(packet->data + match_ofs, match_buf,
                        match_len) == 0))) {
            *data = packet->data;
            *data_len = packet->data_len;

            /* unlink struct */
            if (packet->prev) {
                packet->prev->next = packet->next;
            } else {
                session->packets.head = packet->next;
            }

            if (packet->next) {
                packet->next->prev = packet->prev;
            } else {
                session->packets.tail = packet->prev;
            }

            LIBSSH2_FREE(session, packet);

            return 0;
        }
        packet = packet->next;
    }
    return -1;
}
Example #30
0
/* {{{ libssh2_packet_ask
 * Scan the brigade for a matching packet type, optionally poll the socket for a packet first
 */
int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len,
													unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket)
{
	LIBSSH2_PACKET *packet = session->packets.head;

	if (poll_socket) {
		if (libssh2_packet_read(session, 0) < 0) {
			return -1;
		}
	}
#ifdef LIBSSH2_DEBUG_TRANSPORT
	_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Looking for packet of type: %d", (int)packet_type);
#endif
	while (packet) {
		if (packet->data[0] == packet_type &&
			(packet->data_len >= (match_ofs + match_len)) &&
			(!match_buf || (memcmp(packet->data + match_ofs, match_buf, match_len) == 0))) {
			*data = packet->data;
			*data_len = packet->data_len;

			if (packet->prev) {
				packet->prev->next = packet->next;
			} else {
				session->packets.head = packet->next;
			}

			if (packet->next) {
				packet->next->prev = packet->prev;
			} else {
				session->packets.tail = packet->prev;
			}

			LIBSSH2_FREE(session, packet);

			return 0;
		}
		packet = packet->next;
	}
	return -1;
}