int
gkm_rpc_message_parse (GkmRpcMessage *msg, GkmRpcMessageType type)
{
	const unsigned char *val;
	size_t len;
	uint32_t call_id;

	msg->parsed = 0;

	/* Pull out the call identifier */
	if (!egg_buffer_get_uint32 (&msg->buffer, msg->parsed, &(msg->parsed), &call_id)) {
		gkm_rpc_warn ("invalid message: couldn't read call identifier");
		return 0;
	}

	msg->signature = msg->sigverify = NULL;

	/* If it's an error code then no more processing */
	if (call_id == GKM_RPC_CALL_ERROR) {
		if (type == GKM_RPC_REQUEST) {
			gkm_rpc_warn ("invalid message: error code in request");
			return 0;
		}

		return 1;
	}

	/* The call id and signature */
	if (call_id <= 0 || call_id >= GKM_RPC_CALL_MAX) {
		gkm_rpc_warn ("invalid message: bad call id: %d", call_id);
		return 0;
	}
	if (type == GKM_RPC_REQUEST)
		msg->signature = gkm_rpc_calls[call_id].request;
	else if (type == GKM_RPC_RESPONSE)
		msg->signature = gkm_rpc_calls[call_id].response;
	else
		assert (0 && "invalid message type");
	msg->call_id = call_id;
	msg->call_type = type;
	msg->sigverify = msg->signature;

	/* Verify the incoming signature */
	if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &(msg->parsed), &val, &len)) {
		gkm_rpc_warn ("invalid message: couldn't read signature");
		return 0;
	}

	if ((strlen (msg->signature) != len) || (memcmp (val, msg->signature, len) != 0)) {
		gkm_rpc_warn ("invalid message: signature doesn't match");
		return 0;
	}

	return 1;
}
Ejemplo n.º 2
0
static gboolean
read_full_item_info (EggBuffer *buffer, gsize *offset, ItemInfo *items, guint n_items)
{
	gchar *reserved;
	guint32 tmp;
	gint i, j;

	g_assert (buffer);
	g_assert (offset);
	g_assert (items);

	for (i = 0; i < n_items; i++) {

		/* The display name */
		if (!buffer_get_utf8_string (buffer, *offset, offset,
		                             &items[i].display_name))
			return FALSE;

		/* The secret */
		if (!egg_buffer_get_byte_array (buffer, *offset, offset,
		                                &items[i].ptr_secret, &items[i].n_secret))
			return FALSE;

		/* The item times */
		if (!buffer_get_time (buffer, *offset, offset, &items[i].ctime) ||
		    !buffer_get_time (buffer, *offset, offset, &items[i].mtime))
			return FALSE;

		/* Reserved data */
		reserved = NULL;
		if (!buffer_get_utf8_string (buffer, *offset, offset, &reserved))
			return FALSE;
		g_free (reserved);
		for (j = 0; j < 4; j++) {
			if (!egg_buffer_get_uint32 (buffer, *offset, offset, &tmp))
				return FALSE;
		}

		/* The attributes */
		if (items[i].attributes)
			g_hash_table_unref (items[i].attributes);
		if (!buffer_get_attributes (buffer, *offset, offset, &items[i].attributes, FALSE))
			return FALSE;

		/* The ACLs */
		if (!decode_acl (buffer, *offset, offset, &items[i].acl))
			return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 3
0
static gboolean
read_mpi (EggBuffer *req, gsize *offset, gcry_mpi_t *mpi)
{
	const guchar *data;
	gsize len;
	gcry_error_t gcry;

	if (!egg_buffer_get_byte_array (req, *offset, offset, &data, &len))
		return FALSE;

	gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_USG, data, len, NULL);
	if (gcry)
		return FALSE;

	return TRUE;
}
Ejemplo n.º 4
0
gboolean
gkd_ssh_agent_proto_read_mpi (EggBuffer *req, gsize *offset, GckAttributes *attrs,
                              CK_ATTRIBUTE_TYPE type)
{
	const guchar *data;
	gsize len;

	if (!egg_buffer_get_byte_array (req, *offset, offset, &data, &len))
		return FALSE;

	/* Convert to unsigned format */
	if (len >= 2 && data[0] == 0 && (data[1] & 0x80)) {
		++data;
		--len;
	}

	gck_attributes_add_data (attrs, type, data, len);
	return TRUE;
}
int
gkm_rpc_message_read_space_string (GkmRpcMessage *msg, CK_UTF8CHAR* buffer, CK_ULONG length)
{
	const unsigned char *data;
	size_t n_data;

	assert (msg);
	assert (buffer);
	assert (length);

	assert (!msg->signature || gkm_rpc_message_verify_part (msg, "s"));

	if (!egg_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, &data, &n_data))
		return 0;

	if (n_data != length) {
		gkm_rpc_warn ("invalid length space padded string received: %d != %d", length, n_data);
		return 0;
	}

	memcpy (buffer, data, length);
	return 1;
}