示例#1
0
SilcBuffer silc_client_attributes_request(SilcAttribute attribute, ...)
{
  va_list va;
  SilcBuffer buffer = NULL;

  if (!attribute)
    return silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO,
					  SILC_ATTRIBUTE_USER_ICON,
					  SILC_ATTRIBUTE_SERVICE,
					  SILC_ATTRIBUTE_STATUS_MOOD,
					  SILC_ATTRIBUTE_STATUS_FREETEXT,
					  SILC_ATTRIBUTE_STATUS_MESSAGE,
					  SILC_ATTRIBUTE_PREFERRED_LANGUAGE,
					  SILC_ATTRIBUTE_PREFERRED_CONTACT,
					  SILC_ATTRIBUTE_TIMEZONE,
					  SILC_ATTRIBUTE_GEOLOCATION,
					  SILC_ATTRIBUTE_DEVICE_INFO,
					  SILC_ATTRIBUTE_USER_PUBLIC_KEY, 0);

  va_start(va, attribute);
  while (attribute) {
    buffer = silc_attribute_payload_encode(buffer, attribute, 0, NULL, 0);
    attribute = (SilcAttribute)va_arg(va, SilcUInt32);
  }
  va_end(va);

  return buffer;
}
示例#2
0
static void silc_client_attributes_process_foreach(void *key, void *context,
						   void *user_context)
{
  SilcAttribute attribute = (SilcAttribute)SILC_PTR_TO_32(key);
  SilcAttributePayload attr = context;
  SilcAttrForeach *f = user_context;
  const unsigned char *data;
  unsigned char tmp[32];
  SilcUInt32 data_len;

  if (!context) {
    SILC_LOG_DEBUG(("Attribute %d was not set", attribute));

    /* USER_PUBLIC_KEY we have set earlier */
    if (attribute == SILC_ATTRIBUTE_USER_PUBLIC_KEY)
      return;

    /* The requested attribute was not found */
    f->buffer = silc_attribute_payload_encode(f->buffer, attribute,
					      SILC_ATTRIBUTE_FLAG_INVALID,
					      NULL, 0);
    return;
  }

  SILC_LOG_DEBUG(("Attribute %d found", attribute));
  data = silc_attribute_get_data(attr, &data_len);

  /* We replace the TIMEZONE with valid value here */
  if (attribute == SILC_ATTRIBUTE_TIMEZONE) {
    if (silc_timezone(tmp, sizeof(tmp))) {
      data = tmp;
      data_len = strlen(tmp);
      f->buffer = silc_attribute_payload_encode(f->buffer, attribute,
						SILC_ATTRIBUTE_FLAG_VALID,
						(void *)data, data_len);
    }
    return;
  }

  f->buffer = silc_attribute_payload_encode_data(f->buffer, attribute,
						 SILC_ATTRIBUTE_FLAG_VALID,
						 data, data_len);
}
示例#3
0
文件: buddy.c 项目: dylex/pidgin
static void
silcpurple_add_buddy_i(PurpleConnection *gc, PurpleBuddy *b, gboolean init)
{
	SilcPurple sg = gc->proto_data;
	SilcClient client = sg->client;
	SilcClientConnection conn = sg->conn;
	SilcPurpleBuddyRes r;
	SilcBuffer attrs;
	const char *filename, *name = b->name;

	r = silc_calloc(1, sizeof(*r));
	if (!r)
		return;
	r->client = client;
	r->conn = conn;
	r->b = b;
	r->init = init;

	/* See if we have this buddy's public key.  If we do use that
	   to search the details. */
	filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");
	if (filename) {
		SilcPublicKey public_key;
		SilcAttributeObjPk userpk;

		if (!silc_pkcs_load_public_key(filename, &public_key,
					       SILC_PKCS_FILE_PEM) &&
		    !silc_pkcs_load_public_key(filename, &public_key,
					       SILC_PKCS_FILE_BIN))
			return;

		/* Get all attributes, and use the public key to search user */
		name = NULL;
		attrs = silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO,
						       SILC_ATTRIBUTE_SERVICE,
						       SILC_ATTRIBUTE_STATUS_MOOD,
						       SILC_ATTRIBUTE_STATUS_FREETEXT,
						       SILC_ATTRIBUTE_STATUS_MESSAGE,
						       SILC_ATTRIBUTE_PREFERRED_LANGUAGE,
						       SILC_ATTRIBUTE_PREFERRED_CONTACT,
						       SILC_ATTRIBUTE_TIMEZONE,
						       SILC_ATTRIBUTE_GEOLOCATION,
#ifdef SILC_ATTRIBUTE_USER_ICON
						       SILC_ATTRIBUTE_USER_ICON,
#endif
						       SILC_ATTRIBUTE_DEVICE_INFO, 0);
		userpk.type = "silc-rsa";
		userpk.data = silc_pkcs_public_key_encode(public_key, &userpk.data_len);
		attrs = silc_attribute_payload_encode(attrs,
						      SILC_ATTRIBUTE_USER_PUBLIC_KEY,
						      SILC_ATTRIBUTE_FLAG_VALID,
						      &userpk, sizeof(userpk));
		silc_free(userpk.data);
		silc_pkcs_public_key_free(public_key);
		r->pubkey_search = TRUE;
	} else {
		/* Get all attributes */
		attrs = silc_client_attributes_request(0);
	}

	/* Resolve */
	silc_client_get_clients_whois(client, conn, name, NULL, attrs,
				      silcpurple_add_buddy_resolved, r);
	silc_buffer_free(attrs);
}
示例#4
0
SilcBuffer silc_client_attributes_process(SilcClient client,
					  SilcClientConnection conn,
					  SilcDList attrs)
{
  SilcBuffer buffer = NULL;
  SilcAttrForeach f;
  SilcAttribute attribute;
  SilcAttributePayload attr;
  SilcAttributeObjPk pk;
  unsigned char sign[2048 + 1];
  SilcUInt32 sign_len;

  SILC_LOG_DEBUG(("Process Requested Attributes"));

  /* If nothing is set by application assume that we don't want to use
     attributes, ignore the request. */
  if (!conn->internal->attrs) {
    SILC_LOG_DEBUG(("User has not set any attributes"));
    return NULL;
  }

  /* Always put our public key. */
  pk.type = "silc-rsa";
  pk.data = silc_pkcs_public_key_encode(conn->public_key, &pk.data_len);
  buffer = silc_attribute_payload_encode(buffer,
					 SILC_ATTRIBUTE_USER_PUBLIC_KEY,
					 pk.data ? SILC_ATTRIBUTE_FLAG_VALID :
					 SILC_ATTRIBUTE_FLAG_INVALID,
					 &pk, sizeof(pk));
  silc_free(pk.data);

  /* Go through all requested attributes */
  f.buffer = buffer;
  silc_dlist_start(attrs);
  while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
    /* Put all attributes of this type */
    attribute = silc_attribute_get_attribute(attr);

    /* Ignore signature since we will compute it later */
    if (attribute == SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE)
      continue;

    silc_hash_table_find_foreach(conn->internal->attrs,
				 SILC_32_TO_PTR(attribute),
				 silc_client_attributes_process_foreach,
				 &f);
  }
  buffer = f.buffer;

  /* Finally compute the digital signature of all the data we provided. */
  if (silc_pkcs_sign(conn->private_key, silc_buffer_data(buffer),
		     silc_buffer_len(buffer), sign, sizeof(sign), &sign_len,
		     TRUE, conn->internal->sha1hash)) {
    pk.type = NULL;
    pk.data = sign;
    pk.data_len = sign_len;
    buffer =
      silc_attribute_payload_encode(buffer,
				    SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE,
				    SILC_ATTRIBUTE_FLAG_VALID,
				    &pk, sizeof(pk));
  }

  return buffer;
}