Exemplo n.º 1
0
SilcClientEntry
silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
		       char *userinfo, SilcClientID *id,
		       SilcServerEntry router, void *connection)
{
  SilcClientEntry client;
  char *nicknamec = NULL;

  SILC_LOG_DEBUG(("Adding new client entry"));

  /* Normalize name.  This is cached, original is in client context.  */
  if (nickname) {
    nicknamec = silc_identifier_check(nickname, strlen(nickname),
				      SILC_STRING_UTF8, 128, NULL);
    if (!nicknamec)
      return NULL;
  }

  /* Check username. */
  if (username) {
    char u[128 + 1], h[256 + 1];
    int ret;

    ret = silc_parse_userfqdn(username, u, sizeof(u), h, sizeof(h));
    if (!ret)
      return NULL;
    if (!silc_identifier_verify(u, strlen(u), SILC_STRING_UTF8, 128))
      return NULL;
    if (ret > 1 && !silc_identifier_verify(h, strlen(h),
					   SILC_STRING_UTF8, 256))
      return NULL;
  }

  client = silc_calloc(1, sizeof(*client));
  if (!client)
    return NULL;
  client->nickname = nickname;
  client->username = username ? strdup(username) : NULL;
  client->userinfo = userinfo;
  client->id = id;
  client->router = router;
  client->connection = connection;
  client->channels = silc_hash_table_alloc(3, silc_hash_ptr, NULL,
					   NULL, NULL, NULL, NULL, TRUE);

  if (!silc_idcache_add(id_list->clients, nicknamec, (void *)client->id,
			(void *)client)) {
    silc_hash_table_free(client->channels);
    silc_free(client);
    silc_free(nicknamec);
    return NULL;
  }

  return client;
}
Exemplo n.º 2
0
SilcChannelEntry
silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
			SilcChannelID *id, SilcServerEntry router,
			SilcCipher send_key, SilcCipher receive_key,
			SilcHmac hmac)
{
  SilcChannelEntry channel;
  char *channel_namec = NULL;

  SILC_LOG_DEBUG(("Adding new channel %s", channel_name));

  /* Normalize name.  This is cached, original is in client context.  */
  if (channel_name) {
    channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
					    SILC_STRING_UTF8, 256, NULL);
    if (!channel_namec)
      return NULL;
  }

  channel = silc_calloc(1, sizeof(*channel));
  channel->channel_name = channel_name;
  channel->mode = mode;
  channel->id = id;
  channel->router = router;
  channel->send_key = send_key;
  channel->receive_key = receive_key;
  channel->hmac = hmac;
  channel->created = channel->updated = time(0);
  if (!channel->hmac)
    if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) {
      silc_free(channel);
      return NULL;
    }

  channel->user_list = silc_hash_table_alloc(3, silc_hash_ptr, NULL, NULL,
					     NULL, NULL, NULL, TRUE);

  if (!silc_idcache_add(id_list->channels, channel_namec,
			(void *)channel->id, (void *)channel)) {
    silc_hmac_free(channel->hmac);
    silc_hash_table_free(channel->user_list);
    silc_free(channel);
    silc_free(channel_namec);
    return NULL;
  }

  return channel;
}
Exemplo n.º 3
0
SilcMime silc_mime_alloc(void)
{
    SilcMime mime;

    mime = silc_calloc(1, sizeof(*mime));
    if (!mime)
        return NULL;

    mime->fields = silc_hash_table_alloc(0, silc_hash_string, mime,
                                         silc_hash_string_compare, mime,
                                         silc_mime_field_dest, mime, TRUE);
    if (!mime->fields) {
        silc_mime_free(mime);
        return NULL;
    }

    return mime;
}
Exemplo n.º 4
0
SilcMimeAssembler silc_mime_assembler_alloc(void)
{
    SilcMimeAssembler assembler;

    assembler = silc_calloc(1, sizeof(*assembler));
    if (!assembler)
        return NULL;

    assembler->fragments =
        silc_hash_table_alloc(0, silc_hash_string, NULL,
                              silc_hash_string_compare, NULL,
                              silc_mime_assembler_dest, assembler, TRUE);
    if (!assembler->fragments) {
        silc_mime_assembler_free(assembler);
        return NULL;
    }

    return assembler;
}
Exemplo n.º 5
0
SilcAttributePayload silc_client_attribute_add(SilcClient client,
					       SilcClientConnection conn,
					       SilcAttribute attribute,
					       void *object,
					       SilcUInt32 object_size)
{
  SilcAttributePayload attr;

  attr = silc_attribute_payload_alloc(attribute, SILC_ATTRIBUTE_FLAG_VALID,
				      object, object_size);
  if (!attr)
    return NULL;

  if (!conn->internal->attrs)
    conn->internal->attrs =
      silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
			    NULL, silc_client_attribute_destruct,
			    NULL, TRUE);
  silc_hash_table_add(conn->internal->attrs,
		      SILC_32_TO_PTR(attribute), attr);
  return attr;
}
Exemplo n.º 6
0
SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial)
{
    char *type, *id = NULL, *tmp;
    SilcHashTable f;
    SilcMime p, complete;
    int i, number, total = -1;
    const unsigned char *data;
    SilcUInt32 data_len;
    SilcBuffer compbuf = NULL;

    SILC_LOG_DEBUG(("Assembling MIME fragments"));

    if (!assembler || !partial)
        goto err;

    type = (char *)silc_mime_get_field(partial, "Content-Type");
    if (!type)
        goto err;

    /* Get ID */
    tmp = strstr(type, "id=");
    if (!tmp)
        goto err;
    if (strlen(tmp) <= 4)
        goto err;
    tmp += 3;
    if (*tmp == '"')
        tmp++;
    id = strdup(tmp);
    if (strchr(id, ';'))
        *strchr(id, ';') = '\0';
    if (strrchr(id, '"'))
        *strrchr(id, '"') = '\0';

    SILC_LOG_DEBUG(("Fragment ID %s", id));

    /* Get fragment number */
    tmp = strstr(type, "number=");
    if (!tmp)
        goto err;
    tmp = strchr(tmp, '=');
    if (strlen(tmp) < 2)
        goto err;
    tmp++;
    if (strchr(tmp, ';')) {
        tmp = strdup(tmp);
        *strchr(tmp, ';') = '\0';
        number = atoi(tmp);
        silc_free(tmp);
    } else {
        number = atoi(tmp);
    }

    SILC_LOG_DEBUG(("Fragment number %d", number));

    /* Find fragments with this ID. */
    if (!silc_hash_table_find(assembler->fragments, (void *)id,
                              NULL, (void *)&f)) {
        /* This is new fragment to new message.  Add to hash table and return. */
        f = silc_hash_table_alloc(0, silc_hash_uint, NULL, NULL, NULL,
                                  silc_mime_assemble_dest, NULL, TRUE);
        if (!f)
            goto err;
        silc_hash_table_add(f, SILC_32_TO_PTR(number), partial);
        silc_hash_table_add(assembler->fragments, id, f);
        return NULL;
    }

    /* Try to get total number */
    tmp = strstr(type, "total=");
    if (tmp) {
        tmp = strchr(tmp, '=');
        if (strlen(tmp) < 2)
            goto err;
        tmp++;
        if (strchr(tmp, ';')) {
            tmp = strdup(tmp);
            *strchr(tmp, ';') = '\0';
            total = atoi(tmp);
            silc_free(tmp);
        } else {
            total = atoi(tmp);
        }

        SILC_LOG_DEBUG(("Fragment total %d", total));
    }

    /* If more fragments to come, add to hash table */
    if (number != total) {
        silc_hash_table_add(f, SILC_32_TO_PTR(number), partial);
        return NULL;
    }

    silc_hash_table_add(f, SILC_32_TO_PTR(number), partial);

    /* Verify that we really have all the fragments */
    if (silc_hash_table_count(f) < total)
        return NULL;

    /* Assemble the complete MIME message now. We get them in order from
       the hash table. */
    for (i = 1; i <= total; i++) {
        if (!silc_hash_table_find(f, SILC_32_TO_PTR(i), NULL, (void *)&p))
            goto err;

        /* The fragment is in the data portion of the partial message */
        data = silc_mime_get_data(p, &data_len);
        if (!data)
            goto err;

        /* Assemble */
        if (!compbuf) {
            compbuf = silc_buffer_alloc_size(data_len);
            if (!compbuf)
                goto err;
            silc_buffer_put(compbuf, data, data_len);
        } else {
            compbuf = silc_buffer_realloc(compbuf, silc_buffer_truelen(compbuf) +
                                          data_len);
            if (!compbuf)
                goto err;
            silc_buffer_put_tail(compbuf, data, data_len);
            silc_buffer_pull_tail(compbuf, data_len);
        }
    }

    /* Now parse the complete MIME message and deliver it */
    complete = silc_mime_decode(NULL, (const unsigned char *)compbuf->head,
                                silc_buffer_truelen(compbuf));
    if (!complete)
        goto err;

    /* Delete the hash table entry. Destructors will free memory */
    silc_hash_table_del(assembler->fragments, (void *)id);
    silc_free(id);
    silc_buffer_free(compbuf);

    return complete;

err:
    silc_free(id);
    if (compbuf)
        silc_buffer_free(compbuf);
    silc_mime_free(partial);
    return NULL;
}