コード例 #1
0
ファイル: silcconfig.c プロジェクト: FabrizioFabbe/runtime
char *silc_config_read_line(SilcConfigFile *file, SilcUInt32 line)
{
  register char *p;
  int len;
  char *ret = NULL, *endbuf;

  if (!file || (line <= 0))
    return NULL;
  for (p = file->base; *p && (*p != EOF); p++) {
    if (line <= 1)
      goto found;
    if (*p == '\n')
      line--;
  }
  return NULL;

 found:
  if ((endbuf = strchr(p, '\n'))) {
    len = endbuf - p;
    if (len > 0)
      ret = silc_memdup(p, len);
  } else {
    ret = silc_memdup(p, strlen(p));
  }
  return ret;
}
コード例 #2
0
ファイル: wb.c プロジェクト: bf4/pidgin-mac
static void
silcpurple_wb_request(SilcClient client, const unsigned char *message,
		      SilcUInt32 message_len, SilcClientEntry sender,
		      SilcChannelEntry channel)
{
	char tmp[256];
	SilcPurpleWbRequest req;
	PurpleConnection *gc;
	SilcPurple sg;

	gc = client->application;
	sg = gc->proto_data;

	/* Open whiteboard automatically if requested */
	if (purple_account_get_bool(sg->account, "open-wb", FALSE)) {
		PurpleWhiteboard *wb;

		if (!channel)
			wb = silcpurple_wb_init(sg, sender);
		else
			wb = silcpurple_wb_init_ch(sg, channel);

		silcpurple_wb_parse(wb->proto_data, wb,
				    (unsigned char *)message,
				    message_len);
		return;
	}

	/* Close any previous unaccepted requests */
	purple_request_close_with_handle(sender);

	if (!channel) {
		g_snprintf(tmp, sizeof(tmp),
			   _("%s sent message to whiteboard. Would you like "
			     "to open the whiteboard?"), sender->nickname);
	} else {
		g_snprintf(tmp, sizeof(tmp),
			   _("%s sent message to whiteboard on %s channel. "
			     "Would you like to open the whiteboard?"),
			   sender->nickname, channel->channel_name);
	}

	req = silc_calloc(1, sizeof(*req));
	if (!req)
		return;
	req->message = silc_memdup(message, message_len);
	req->message_len = message_len;
	req->sender = sender;
	req->channel = channel;
	req->sg = sg;

	purple_request_action(gc, _("Whiteboard"), tmp, NULL, 1,
				sg->account, sender->nickname, NULL, req, 2,
			    _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
			    _("No"), G_CALLBACK(silcpurple_wb_request_cb));
}
コード例 #3
0
ファイル: client_prvmsg.c プロジェクト: TabTwo/silc-client
SilcBool silc_client_add_private_message_key(SilcClient client,
					     SilcClientConnection conn,
					     SilcClientEntry client_entry,
					     const char *cipher,
					     const char *hmac,
					     unsigned char *key,
					     SilcUInt32 key_len)
{
  SilcSKEKeyMaterial keymat;
  SilcBool ret;

  if (!client || !client_entry)
    return FALSE;

  /* Return FALSE if key already set */
  if (client_entry->internal.send_key && client_entry->internal.receive_key)
    return FALSE;

  if (!cipher)
    cipher = SILC_DEFAULT_CIPHER;
  if (!hmac)
    hmac = SILC_DEFAULT_HMAC;

  /* Check the requested cipher and HMAC */
  if (!silc_cipher_is_supported(cipher))
    return FALSE;
  if (!silc_hmac_is_supported(hmac))
    return FALSE;

  /* Save the key */
  client_entry->internal.key = silc_memdup(key, key_len);
  client_entry->internal.key_len = key_len;

  /* Produce the key material as the protocol defines */
  keymat = silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
					      conn->internal->sha1hash);
  if (!keymat)
    return FALSE;

  /* Set the key into use */
  ret = silc_client_add_private_message_key_ske(client, conn, client_entry,
						cipher, hmac, keymat);
  client_entry->internal.generated = FALSE;

  /* Free the key material */
  silc_ske_free_key_material(keymat);

  /* If we are setting the key without a request from the remote client,
     we will send request to remote. */
  if (!client_entry->internal.prv_resp)
    silc_client_send_private_message_key_request(client, conn, client_entry);

  return ret;
}
コード例 #4
0
ファイル: silcmime.c プロジェクト: TabTwo/silc-server
void silc_mime_add_data(SilcMime mime, const unsigned char *data,
                        SilcUInt32 data_len)
{
    if (!mime || !data)
        return;

    if (mime->data)
        silc_free(mime->data);

    mime->data = silc_memdup(data, data_len);
    mime->data_len = data_len;
}
コード例 #5
0
ファイル: silccommand.c プロジェクト: FabrizioFabbe/silc
SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
					   SilcUInt16 ident,
					   SilcUInt32 argc, va_list ap)
{
  unsigned char **argv = NULL;
  SilcUInt32 *argv_lens = NULL, *argv_types = NULL;
  unsigned char *x;
  SilcUInt32 x_len;
  SilcUInt32 x_type;
  SilcBuffer buffer = NULL;
  int i, k = 0;

  if (argc) {
    argv = silc_calloc(argc, sizeof(unsigned char *));
    if (!argv)
      return NULL;
    argv_lens = silc_calloc(argc, sizeof(SilcUInt32));
    if (!argv_lens)
      return NULL;
    argv_types = silc_calloc(argc, sizeof(SilcUInt32));
    if (!argv_types)
      return NULL;

    for (i = 0, k = 0; i < argc; i++) {
      x_type = va_arg(ap, SilcUInt32);
      x = va_arg(ap, unsigned char *);
      x_len = va_arg(ap, SilcUInt32);

      if (!x_type || !x || !x_len)
	continue;

      argv[k] = silc_memdup(x, x_len);
      if (!argv[k])
	goto out;
      argv_lens[k] = x_len;
      argv_types[k] = x_type;
      k++;
    }
  }

  buffer = silc_command_payload_encode(cmd, k, argv, argv_lens,
				       argv_types, ident);

 out:
  for (i = 0; i < k; i++)
    silc_free(argv[i]);
  silc_free(argv);
  silc_free(argv_lens);
  silc_free(argv_types);

  return buffer;
}
コード例 #6
0
SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
				      char **ip)
{
  SilcSymbianSocket *s = (SilcSymbianSocket *)sock;
  TInetAddr addr;
  char host[256];
  TBuf<64> tmp;

  if (hostname)
    *hostname = NULL;
  *ip = NULL;

  s->sock->LocalName(addr);
  addr.Output(tmp);

  *ip = (char *)silc_memdup(tmp.Ptr(), tmp.Length());
  if (*ip == NULL)
    return FALSE;

  /* Do reverse lookup if we want hostname too. */
  if (hostname) {
    /* Get host by address */
    if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))
      return FALSE;

    *hostname = (char *)silc_memdup(host, strlen(host));
    SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));

    /* Reverse */
    if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host)))
      return FALSE;

    if (strcmp(*ip, host))
      return FALSE;
  }

  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
  return TRUE;
}
コード例 #7
0
ファイル: silcmemory.c プロジェクト: FabrizioFabbe/runtime
void *silc_smemdup(SilcStack stack, const void *ptr, SilcUInt32 size)
{
  unsigned char *addr;

  if (!stack)
    return silc_memdup(ptr, size);

  addr = silc_stack_malloc(stack, size + 1);
  if (silc_unlikely(!addr))
    return NULL;
  memcpy((void *)addr, ptr, size);
  addr[size] = '\0';
  return (void *)addr;
}
コード例 #8
0
ファイル: silcmemory.c プロジェクト: FabrizioFabbe/runtime
char *silc_sstrdup(SilcStack stack, const char *str)
{
  SilcInt32 size = strlen(str);
  char *addr;

  if (!stack)
    return silc_memdup(str, size);

  addr = silc_stack_malloc(stack, size + 1);
  if (silc_unlikely(!addr))
    return NULL;
  memcpy((void *)addr, str, size);
  addr[size] = '\0';
  return addr;
}
コード例 #9
0
ファイル: client_connect.c プロジェクト: TabTwo/silc-client
static void silc_client_connect_auth_method(SilcAuthMethod auth_meth,
					    const void *auth,
					    SilcUInt32 auth_len,
					    void *context)
{
  SilcFSMThread fsm = context;
  SilcClientConnection conn = silc_fsm_get_context(fsm);

  conn->internal->params.auth_method = auth_meth;
  if (auth_meth == SILC_AUTH_PASSWORD)
    conn->internal->params.auth = silc_memdup(auth, auth_len);
  else
    conn->internal->params.auth = (void *)auth;
  conn->internal->params.auth_len = auth_len;

  SILC_FSM_CALL_CONTINUE(fsm);
}
コード例 #10
0
ファイル: command_reply.c プロジェクト: TabTwo/silc-server
static char
silc_server_command_reply_whois_save_client(SilcServerCommandReplyContext cmd)
{
  unsigned char *tmp;
  SilcUInt32 len;
  SilcClientEntry client = silc_packet_get_context(cmd->sock);

  /* Take Requested Attributes if set. */
  tmp = silc_argument_get_arg_type(cmd->args, 11, &len);
  if (tmp && client) {
    silc_free(client->attrs);
    client->attrs = silc_memdup(tmp, len);
    client->attrs_len = len;
  }

  client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;

  return TRUE;
}
コード例 #11
0
ファイル: silccommand.c プロジェクト: FabrizioFabbe/silc
SilcBuffer
silc_command_reply_payload_encode_vap(SilcCommand cmd,
				      SilcStatus status,
				      SilcStatus error,
				      SilcUInt16 ident, SilcUInt32 argc,
				      va_list ap)
{
  unsigned char **argv;
  SilcUInt32 *argv_lens = NULL, *argv_types = NULL;
  unsigned char status_data[2];
  unsigned char *x;
  SilcUInt32 x_len;
  SilcUInt32 x_type;
  SilcBuffer buffer = NULL;
  int i, k;

  argc++;
  argv = silc_calloc(argc, sizeof(unsigned char *));
  if (!argv)
    return NULL;
  argv_lens = silc_calloc(argc, sizeof(SilcUInt32));
  if (!argv_lens) {
    silc_free(argv);
    return NULL;
  }
  argv_types = silc_calloc(argc, sizeof(SilcUInt32));
  if (!argv_types) {
    silc_free(argv_lens);
    silc_free(argv);
    return NULL;
  }

  status_data[0] = status;
  status_data[1] = error;
  argv[0] = silc_memdup(status_data, sizeof(status_data));
  if (!argv[0]) {
    silc_free(argv_types);
    silc_free(argv_lens);
    silc_free(argv);
    return NULL;
  }
  argv_lens[0] = sizeof(status_data);
  argv_types[0] = 1;

  for (i = 1, k = 1; i < argc; i++) {
    x_type = va_arg(ap, SilcUInt32);
    x = va_arg(ap, unsigned char *);
    x_len = va_arg(ap, SilcUInt32);

    if (!x_type || !x || !x_len)
      continue;

    argv[k] = silc_memdup(x, x_len);
    if (!argv[k])
      goto out;
    argv_lens[k] = x_len;
    argv_types[k] = x_type;
    k++;
  }

  buffer = silc_command_payload_encode(cmd, k, argv, argv_lens,
				       argv_types, ident);

 out:
  for (i = 0; i < k; i++)
    silc_free(argv[i]);
  silc_free(argv);
  silc_free(argv_lens);
  silc_free(argv_types);

  return buffer;
}
コード例 #12
0
ファイル: silcnotify.c プロジェクト: FabrizioFabbe/silc
SilcBuffer silc_notify_payload_encode(SilcNotifyType type, SilcUInt32 argc,
				      va_list ap)
{
  SilcBuffer buffer;
  SilcBuffer args = NULL;
  unsigned char **argv;
  SilcUInt32 *argv_lens = NULL, *argv_types = NULL;
  unsigned char *x;
  SilcUInt32 x_len, len = 0;
  int i, k = 0;

  if (argc) {
    argv = silc_calloc(argc, sizeof(unsigned char *));
    if (!argv)
      return NULL;
    argv_lens = silc_calloc(argc, sizeof(SilcUInt32));
    if (!argv_lens) {
      silc_free(argv);
      return NULL;
    }
    argv_types = silc_calloc(argc, sizeof(SilcUInt32));
    if (!argv_types) {
      silc_free(argv_lens);
      silc_free(argv);
      return NULL;
    }

    for (i = 0, k = 0; i < argc; i++) {
      x = va_arg(ap, unsigned char *);
      x_len = va_arg(ap, SilcUInt32);

      if (!x || !x_len)
	continue;

      argv[k] = silc_memdup(x, x_len);
      if (!argv[k])
	return NULL;
      argv_lens[k] = x_len;
      argv_types[k] = i + 1;
      k++;
    }

    args = silc_argument_payload_encode(k, argv, argv_lens, argv_types);
    len = silc_buffer_len(args);

    for (i = 0; i < k; i++)
      silc_free(argv[i]);
    silc_free(argv);
    silc_free(argv_lens);
    silc_free(argv_types);
  }

  len += 5;
  buffer = silc_buffer_alloc_size(len);
  if (!buffer)
    return NULL;
  silc_buffer_format(buffer,
		     SILC_STR_UI_SHORT(type),
		     SILC_STR_UI_SHORT(len),
		     SILC_STR_UI_CHAR(k),
		     SILC_STR_END);

  if (k) {
    silc_buffer_format(buffer,
		       SILC_STR_OFFSET(5),
		       SILC_STR_DATA(args->data, silc_buffer_len(args)),
		       SILC_STR_END);
    silc_buffer_free(args);
  }

  return buffer;
}
コード例 #13
0
ファイル: silcattrs.c プロジェクト: TabTwo/silc-client
SilcBool silc_attribute_get_object(SilcAttributePayload payload,
				   void *object, SilcUInt32 object_size)
{
  SilcUInt16 len;
  SilcBool ret = FALSE;

  if (!object || payload->flags & SILC_ATTRIBUTE_FLAG_INVALID)
    return FALSE;

  switch (payload->attribute) {
  case SILC_ATTRIBUTE_USER_INFO:
    {
      SilcVCard vcard = object;
      if (object_size != sizeof(*vcard))
	break;
      if (!silc_vcard_decode(payload->data, payload->data_len, vcard))
	break;
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_SERVICE:
    {
      SilcAttributeObjService *service = object;
      SilcBufferStruct buf;
      SilcUInt16 addr_len, signon_len;
      char *addr, *signon;
      int res;
      if (object_size != sizeof(*service))
	break;
      if (payload->data_len < 13)
	break;
      silc_buffer_set(&buf, payload->data, payload->data_len);
      res = silc_buffer_unformat(&buf,
				 SILC_STR_UI_INT(&service->port),
				 SILC_STR_UI16_NSTRING(&addr, &addr_len),
				 SILC_STR_UI_CHAR(&service->status),
				 SILC_STR_UI16_NSTRING(&signon, &signon_len),
				 SILC_STR_UI_INT(&service->idle),
				 SILC_STR_END);
      if (res == -1)
	break;
      memset(service->address, 0, sizeof(service->address));
      memset(service->signon, 0, sizeof(service->signon));
      memcpy(service->address, addr,
	     (addr_len < sizeof(service->address) - 1 ? addr_len :
	      sizeof(service->address) - 1));
      memcpy(service->signon, signon,
	     (signon_len < sizeof(service->signon) - 1 ? signon_len :
	      sizeof(service->signon) - 1));
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_STATUS_MOOD:
  case SILC_ATTRIBUTE_PREFERRED_CONTACT:
    {
      SilcUInt32 *mask = (SilcUInt32 *)object;
      if (object_size != sizeof(SilcUInt32))
	break;
      if (payload->data_len < 4)
	break;
      SILC_GET32_MSB(*mask, payload->data);
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_STATUS_FREETEXT:
  case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
  case SILC_ATTRIBUTE_TIMEZONE:
    {
      char *string = object;
      if (payload->data_len < 2)
	break;
      SILC_GET16_MSB(len, payload->data);
      if (payload->data_len < 2 + len)
	break;
      if (object_size < len)
	break;
      memcpy(string, payload->data + 2, len);
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_STATUS_MESSAGE:
  case SILC_ATTRIBUTE_EXTENSION:
  case SILC_ATTRIBUTE_USER_ICON:
    {
      SilcMime mime = object;
      if (object_size != sizeof(*mime))
	break;
      if (!silc_mime_decode(mime, payload->data, payload->data_len))
	break;
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_GEOLOCATION:
    {
      SilcAttributeObjGeo *geo = object;
      SilcBufferStruct buffer;
      int res;
      if (object_size != sizeof(*geo))
	break;
      silc_buffer_set(&buffer, (unsigned char *)payload->data,
		      payload->data_len);
      res = silc_buffer_unformat(&buffer,
				 SILC_STR_UI16_STRING_ALLOC(&geo->longitude),
				 SILC_STR_UI16_STRING_ALLOC(&geo->latitude),
				 SILC_STR_UI16_STRING_ALLOC(&geo->altitude),
				 SILC_STR_UI16_STRING_ALLOC(&geo->accuracy),
				 SILC_STR_END);
      if (res == -1)
	break;
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_DEVICE_INFO:
    {
      SilcAttributeObjDevice *dev = object;
      SilcBufferStruct buffer;
      SilcUInt32 type;
      int res;
      if (object_size != sizeof(*dev))
	break;
      silc_buffer_set(&buffer, (unsigned char *)payload->data,
		      payload->data_len);
      res =
	silc_buffer_unformat(&buffer,
			     SILC_STR_UI_INT(&type),
			     SILC_STR_UI16_STRING_ALLOC(&dev->manufacturer),
			     SILC_STR_UI16_STRING_ALLOC(&dev->version),
			     SILC_STR_UI16_STRING_ALLOC(&dev->model),
			     SILC_STR_UI16_STRING_ALLOC(&dev->language),
			     SILC_STR_END);
      if (res == -1)
	break;
      dev->type = type;
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_PHONE_NUMBER:
    {
      SilcAttributeObjPN *pn = object;
      SilcBufferStruct buffer;
      SilcUInt32 pn_format;
      int res;
      if (object_size != sizeof(*pn))
	break;
      silc_buffer_set(&buffer, (unsigned char *)payload->data,
		      payload->data_len);
      res =
	silc_buffer_unformat(&buffer,
			     SILC_STR_UI_INT(&pn_format),
			     SILC_STR_UI16_STRING_ALLOC(&pn->number),
			     SILC_STR_END);
      if (res == -1)
	break;
      pn->format = pn_format;
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
  case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
    {
      SilcAttributeObjPk *pk = object;
      SilcBufferStruct buffer;
      int res;
      if (object_size != sizeof(*pk))
	break;
      silc_buffer_set(&buffer, (unsigned char *)payload->data,
		      payload->data_len);
      res =
	silc_buffer_unformat(&buffer,
			     SILC_STR_UI16_NSTRING_ALLOC(&pk->type, &len),
			     SILC_STR_END);
      if (res == -1 || len > silc_buffer_len(&buffer) - 2)
	break;
      pk->data = silc_memdup(payload->data + 2 + len,
			     payload->data_len - 2 - len);
      pk->data_len = payload->data_len - 2 - len;
      ret = TRUE;
    }
    break;

  case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
  case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
    {
      SilcAttributeObjPk *pk = object;
      if (object_size != sizeof(*pk))
	break;
      pk->type = NULL;
      pk->data = silc_memdup(payload->data, payload->data_len);
      pk->data_len = payload->data_len;
      ret = TRUE;
    }
    break;

  default:
    break;
  }

  return ret;
}
コード例 #14
0
ファイル: silcmemory.c プロジェクト: FabrizioFabbe/runtime
char *silc_strdup(const char *str)
{
  return silc_memdup(str, strlen(str));
}
コード例 #15
0
ファイル: silcstringprep.c プロジェクト: TabTwo/silc-toolkit
SilcStringprepStatus
silc_stringprep(const unsigned char *bin, SilcUInt32 bin_len,
		SilcStringEncoding bin_encoding,
		const char *profile_name,
		SilcStringprepFlags flags,
		unsigned char **out, SilcUInt32 *out_len,
		SilcStringEncoding out_encoding)
{
  Stringprep_profile_flags f = 0;
  const Stringprep_profile *profile;
  unsigned char *utf8s;
  SilcUInt32 utf8s_len;
  int ret;

  SILC_LOG_DEBUG(("Preparing string"));

  if (!bin || !bin_len || !profile_name)
    return SILC_STRINGPREP_ERR;

  /* Convert string to UTF-8 */
  utf8s_len = silc_utf8_encoded_len(bin, bin_len, bin_encoding);
  if (!utf8s_len)
    return SILC_STRINGPREP_ERR_ENCODING;
  utf8s = silc_calloc(utf8s_len + 1, sizeof(*utf8s));
  if (!utf8s)
    return SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
  silc_utf8_encode(bin, bin_len, bin_encoding, utf8s, utf8s_len);

  /* Check profile. */
  if (!strcmp(profile_name, SILC_IDENTIFIER_PREP))
    profile = stringprep_silc_identifier_prep;
  else if (!strcmp(profile_name, SILC_IDENTIFIER_CH_PREP))
    profile = stringprep_silc_identifier_ch_prep;
  else if (!strcmp(profile_name, SILC_IDENTIFIERC_PREP))
    profile = stringprep_silc_identifierc_prep;
  else if (!strcmp(profile_name, SILC_CASEFOLD_PREP))
    profile = stringprep_silc_casefold_prep;
  else
    return SILC_STRINGPREP_ERR_UNSUP_PROFILE;

  /* Translate flags */
  if (!(flags & SILC_STRINGPREP_ALLOW_UNASSIGNED))
    f |= STRINGPREP_NO_UNASSIGNED;

  /* Prepare */
  ret = stringprep((char *)utf8s, utf8s_len, f, profile);
  SILC_LOG_DEBUG(("stringprep() return %d", ret));

  /* Since the stringprep() doesn't allocate returned buffer, and
     stringprep_profile() doesn't do it correctly, we can't know how
     much space we must have for the conversion.  Allocate more if it
     fails, and try again. */
  if (ret == STRINGPREP_TOO_SMALL_BUFFER) {
    utf8s = silc_realloc(utf8s, sizeof(*utf8s) * ((utf8s_len * 2) + 1));
    if (!utf8s)
      return SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
    memset(utf8s + utf8s_len + 1, 0, utf8s_len);
    ret = stringprep((char *)utf8s, utf8s_len * 2, f, profile);
    SILC_LOG_DEBUG(("stringprep() return %d", ret));
  }

  switch (ret) {
  case STRINGPREP_OK:
    ret = SILC_STRINGPREP_OK;
    break;

  case STRINGPREP_CONTAINS_UNASSIGNED:
    ret = SILC_STRINGPREP_ERR_UNASSIGNED;
    break;

  case STRINGPREP_CONTAINS_PROHIBITED:
    ret = SILC_STRINGPREP_ERR_PROHIBITED;
    break;

  case STRINGPREP_BIDI_BOTH_L_AND_RAL:
    ret = SILC_STRINGPREP_ERR_BIDI_RAL_WITH_L;
    break;

  case STRINGPREP_BIDI_LEADTRAIL_NOT_RAL:
    ret = SILC_STRINGPREP_ERR_BIDI_RAL;
    break;

  case STRINGPREP_BIDI_CONTAINS_PROHIBITED:
    ret = SILC_STRINGPREP_ERR_BIDI_PROHIBITED;
    break;

  case STRINGPREP_UNKNOWN_PROFILE:
    ret = SILC_STRINGPREP_ERR_UNSUP_PROFILE;
    break;

  case STRINGPREP_MALLOC_ERROR:
    ret = SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
    break;

  default:
    ret = SILC_STRINGPREP_ERR;
    break;
  }

  /* Convert to desired output character encoding */
  if (ret == SILC_STRINGPREP_OK) {
    if (out && out_len) {
      if (out_encoding != SILC_STRING_UTF8) {
	*out_len = silc_utf8_decoded_len(utf8s, strlen(utf8s), out_encoding);
	if (*out_len) {
	  *out = silc_calloc(*out_len + 1, sizeof(**out));
	  if (*out) {
	    silc_utf8_decode(utf8s, strlen(utf8s), out_encoding, *out,
			     *out_len);
	  } else {
	    ret = SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
	  }
	} else {
	  ret = SILC_STRINGPREP_ERR_ENCODING;
	}
      } else {
	*out_len = strlen(utf8s);
	*out = silc_memdup(utf8s, *out_len);
      }
    }
  }

  silc_free(utf8s);

  return (SilcStringprepStatus)ret;
}
コード例 #16
0
ファイル: buddy.c プロジェクト: dylex/pidgin
static void
silcpurple_add_buddy_resolved(SilcClient client,
			    SilcClientConnection conn,
			    SilcClientEntry *clients,
			    SilcUInt32 clients_count,
			    void *context)
{
	SilcPurpleBuddyRes r = context;
	PurpleBuddy *b = r->b;
	SilcAttributePayload pub;
	SilcAttributeObjPk userpk;
	unsigned char *pk;
	SilcUInt32 pk_len;
	const char *filename;

	filename = purple_blist_node_get_string((PurpleBlistNode *)b, "public-key");

	/* If the buddy is offline/nonexistent, we will require user
	   to associate a public key with the buddy or the buddy
	   cannot be added. */
	if (!clients_count) {
		if (r->init) {
			silc_free(r);
			return;
		}

		r->offline = TRUE;
		/* If the user has already associated a public key, try loading it
		 * before prompting the user to load it again */
		if (filename != NULL)
			silcpurple_add_buddy_ask_import(r, filename);
		else
			silcpurple_add_buddy_ask_pk(r);
		return;
	}

	/* If more than one client was found with nickname, we need to verify
	   from user which one is the correct. */
	if (clients_count > 1 && !r->pubkey_search) {
		if (r->init) {
			silc_free(r);
			return;
		}

		silcpurple_add_buddy_select(r, clients, clients_count);
		return;
	}

	/* If we searched using public keys and more than one entry was found
	   the same person is logged on multiple times. */
	if (clients_count > 1 && r->pubkey_search && b->name) {
		if (r->init) {
			/* Find the entry that closest matches to the
			   buddy nickname. */
			int i;
			for (i = 0; i < clients_count; i++) {
				if (!g_ascii_strncasecmp(b->name, clients[i]->nickname,
						 strlen(b->name))) {
					clients[0] = clients[i];
					break;
				}
			}
		} else {
			/* Verify from user which one is correct */
			silcpurple_add_buddy_select(r, clients, clients_count);
			return;
		}
	}

	/* The client was found.  Now get its public key and verify
	   that before adding the buddy. */
	memset(&userpk, 0, sizeof(userpk));
	b->proto_data = silc_memdup(clients[0]->id, sizeof(*clients[0]->id));
	r->client_id = *clients[0]->id;

	/* Get the public key from attributes, if not present then
	   resolve it with GETKEY unless we have it cached already. */
	if (clients[0]->attrs && !clients[0]->public_key) {
		pub = silcpurple_get_attr(clients[0]->attrs,
					SILC_ATTRIBUTE_USER_PUBLIC_KEY);
		if (!pub || !silc_attribute_get_object(pub, (void *)&userpk,
						       sizeof(userpk))) {
			/* Get public key with GETKEY */
			silc_client_command_call(client, conn, NULL,
						 "GETKEY", clients[0]->nickname, NULL);
			silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
						    conn->cmd_ident,
						    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
						    r);
			return;
		}
		if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len,
						 &clients[0]->public_key))
			return;
		silc_free(userpk.data);
	} else if (filename && !clients[0]->public_key) {
		if (!silc_pkcs_load_public_key(filename, &clients[0]->public_key,
					       SILC_PKCS_FILE_PEM) &&
		    !silc_pkcs_load_public_key(filename, &clients[0]->public_key,
					       SILC_PKCS_FILE_BIN)) {
			/* Get public key with GETKEY */
			silc_client_command_call(client, conn, NULL,
						 "GETKEY", clients[0]->nickname, NULL);
			silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
						    conn->cmd_ident,
						    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
						    r);
			return;
		}
	} else if (!clients[0]->public_key) {
		/* Get public key with GETKEY */
		silc_client_command_call(client, conn, NULL,
					 "GETKEY", clients[0]->nickname, NULL);
		silc_client_command_pending(conn, SILC_COMMAND_GETKEY,
					    conn->cmd_ident,
					    (SilcCommandCb)silcpurple_add_buddy_getkey_cb,
					    r);
		return;
	}

	/* We have the public key, verify it. */
	pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len);
	silcpurple_verify_public_key(client, conn, clients[0]->nickname,
				   SILC_SOCKET_TYPE_CLIENT,
				   pk, pk_len, SILC_SKE_PK_TYPE_SILC,
				   silcpurple_add_buddy_save, r);
	silc_free(pk);
}
コード例 #17
0
int main(int argc, char **argv)
{
  SilcArgumentPayload payload;
  SilcBuffer args, args2;
  char arg[ARG_NUM + 2];
  int i;
  unsigned char **argvv, *a;
  SilcUInt32 *argvv_lens, l;
  SilcUInt32 *argvv_types, t;
  SilcBool success = FALSE;

  if (argc > 1 && !strcmp(argv[1], "-d")) {
    silc_debug = 1;
    silc_debug_hexdump = 1;
    silc_log_set_debug_string("*argument*");
  }

  SILC_LOG_DEBUG(("Encoding %d arguments", ARG_NUM));
  argvv = silc_calloc(ARG_NUM, sizeof(unsigned char *));
  argvv_lens = silc_calloc(ARG_NUM, sizeof(SilcUInt32));
  argvv_types = silc_calloc(ARG_NUM, sizeof(SilcUInt32));
  for (i = 0; i < ARG_NUM; i++) {
    memset(arg, 0, sizeof(arg));
    memset(arg, 'a', i + 1);

    SILC_LOG_DEBUG(("Argument %d, len %d, type %d", i + 1,
		   strlen(arg), i + 1));
    SILC_LOG_HEXDUMP(("Argument data"), arg, strlen(arg));

    argvv[i] = silc_memdup(arg, strlen(arg));
    argvv_lens[i] = strlen(arg);
    argvv_types[i] = i + 1;
  }
  args = silc_argument_payload_encode(ARG_NUM, argvv, argvv_lens, argvv_types);
  if (!args)
    goto out;
  SILC_LOG_DEBUG(("Encoding was successful"));


  SILC_LOG_DEBUG(("Adding one extra argument"));
  memset(arg, 0, sizeof(arg));
  memset(arg, 'a', ARG_NUM + 1);
  SILC_LOG_DEBUG(("Argument %d, len %d, type %d", ARG_NUM + 1,
		 strlen(arg), ARG_NUM + 1));
  SILC_LOG_HEXDUMP(("Argument data"), arg, strlen(arg));
  args = silc_argument_payload_encode_one(args, arg, strlen(arg), 
					  ARG_NUM + 1);
  if (!args)
    goto out;
  SILC_LOG_DEBUG(("Adding one argument was successful"));

  SILC_LOG_HEXDUMP(("Encoded payload"), args->data, args->len);


  SILC_LOG_DEBUG(("Parsing the encoded payload"));
  payload = silc_argument_payload_parse(args->data, args->len, ARG_NUM + 1);
  if (!payload)
    goto out;
  SILC_LOG_DEBUG(("Parsing was successful"));


  SILC_LOG_DEBUG(("Re-encoding the parsed payload"));
  args2 = silc_argument_payload_encode_payload(payload);
  if (!args2)
    goto out;
  if (args2->len != args->len ||
      memcmp(args2->data, args->data, args->len)) {
    SILC_LOG_DEBUG(("Re-encoding failed"));
    goto out;
  }
  silc_buffer_free(args2);
  SILC_LOG_DEBUG(("Re-encoding was successful"));


  SILC_LOG_DEBUG(("Checking number of arguments"));
  SILC_LOG_DEBUG(("Number of arguments: %d (expecting %d)",
		 silc_argument_get_arg_num(payload), ARG_NUM + 1));
  if (silc_argument_get_arg_num(payload) != ARG_NUM + 1)
    goto out;


  SILC_LOG_DEBUG(("Traversing the parsed arguments"));
  i = 0;
  a = silc_argument_get_first_arg(payload, &t, &l);
  if (!a || t != argvv_types[0] || l != argvv_lens[0] ||
      memcmp(a, argvv[0], l)) {
    SILC_LOG_DEBUG(("First argument failed"));
    goto out;
  }
  while (a) {
    if (i + 1 == ARG_NUM + 1) {
      SILC_LOG_DEBUG(("Argument %d, len %d (expected %d), "
		      "type %d (expected %d)", i + 1, l, strlen(arg),
		      t, ARG_NUM + 1));
      if (!a || t != ARG_NUM + 1 || l != strlen(arg) ||
	  memcmp(a, arg, l)) {
	SILC_LOG_DEBUG(("Argument %d failed", ARG_NUM + 1));
	goto out;
      }
    } else {
      SILC_LOG_DEBUG(("Argument %d, len %d (expected %d), "
		      "type %d (expected %d)", i + 1, l, argvv_lens[i],
		      t, argvv_types[i]));
      if (!a || t != argvv_types[i] || l != argvv_lens[i] ||
	  memcmp(a, argvv[i], l)) {
	SILC_LOG_DEBUG(("Argument %d failed", i + 1));
	goto out;
      }
    }
    a = silc_argument_get_next_arg(payload, &t, &l);
    i++;
  }
  if (i != ARG_NUM + 1) {
    SILC_LOG_DEBUG(("All arguments was not parsed, missing %d args",
		    ARG_NUM + 1 - i));
    goto out;
  }
  SILC_LOG_DEBUG(("Traversing successful"));


  SILC_LOG_DEBUG(("Traversing arguments by type"));
  for (i = 0; i < ARG_NUM + 1; i++) {
    a = silc_argument_get_arg_type(payload, i + 1, &l);
    if (i + 1 == ARG_NUM + 1) {
      if (!a || t != ARG_NUM + 1 || l != strlen(arg) ||
	  memcmp(a, arg, l)) {
	SILC_LOG_DEBUG(("Argument %d failed", ARG_NUM + 1));
	goto out;
      }
    } else {
      if (!a || l != argvv_lens[i] || memcmp(a, argvv[i], l)) {
	SILC_LOG_DEBUG(("Argument %d failed", i + 1));
	goto out;
      }
    }
  }
  SILC_LOG_DEBUG(("Traversing successful"));

  success = TRUE;

 out:
  silc_argument_payload_free(payload);
  for (i = 0; i < ARG_NUM; i++)
    silc_free(argvv[i]);
  silc_free(argvv);
  silc_free(argvv_lens);
  silc_free(argvv_types);
  silc_buffer_free(args);

  SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
  fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");

  exit(success);
}
コード例 #18
0
ファイル: silcstatus.c プロジェクト: FabrizioFabbe/silc
SilcUInt32 silc_status_get_args(SilcStatus status,
                                SilcArgumentPayload args,
                                void **ret_arg1, void **ret_arg2)
{
    SilcUInt32 num, len;
    unsigned char *tmp;

    assert(ret_arg1 && ret_arg2);

    num = silc_argument_get_arg_num(args);
    if (num > 3)
        return 0;
    if (num == 0)
        return 0;

    switch (status) {

    case SILC_STATUS_ERR_NO_SUCH_NICK:
    case SILC_STATUS_ERR_NO_SUCH_CHANNEL:
    case SILC_STATUS_ERR_NO_SUCH_SERVER:
    case SILC_STATUS_ERR_NO_SUCH_SERVICE:
    case SILC_STATUS_ERR_UNKNOWN_ALGORITHM:
        tmp = silc_argument_get_arg_type(args, 2, &len);
        if (!tmp)
            return 0;
        *ret_arg1 = silc_memdup(tmp, len);
        if (!(*ret_arg1))
            return 0;
        num = 1;
        break;

    case SILC_STATUS_ERR_NO_SUCH_CLIENT_ID:
    case SILC_STATUS_ERR_BAD_CLIENT_ID:
    {
        SilcID id;
        tmp = silc_argument_get_arg_type(args, 2, &len);
        if (!tmp)
            return 0;
        if (silc_id_payload_parse_id(tmp, len, &id))
            return 0;
        *ret_arg1 = silc_id_dup(&id.u.client_id, SILC_ID_CLIENT);
        if (!(*ret_arg1))
            return 0;
        num = 1;
    }
    break;

    case SILC_STATUS_ERR_NO_SUCH_SERVER_ID:
    case SILC_STATUS_ERR_BAD_SERVER_ID:
    {
        SilcID id;
        tmp = silc_argument_get_arg_type(args, 2, &len);
        if (!tmp)
            return 0;
        if (silc_id_payload_parse_id(tmp, len, &id))
            return 0;
        *ret_arg1 = silc_id_dup(&id.u.server_id, SILC_ID_SERVER);
        if (!(*ret_arg1))
            return 0;
        num = 1;
    }
    break;

    case SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID:
    case SILC_STATUS_ERR_BAD_CHANNEL_ID:
    case SILC_STATUS_ERR_NOT_ON_CHANNEL:
    case SILC_STATUS_ERR_CHANNEL_IS_FULL:
    case SILC_STATUS_ERR_NOT_INVITED:
    case SILC_STATUS_ERR_BANNED_FROM_CHANNEL:
    case SILC_STATUS_ERR_NO_CHANNEL_PRIV:
    case SILC_STATUS_ERR_NO_CHANNEL_FOPRIV:
    {
        SilcID id;
        tmp = silc_argument_get_arg_type(args, 2, &len);
        if (!tmp)
            return 0;
        if (silc_id_payload_parse_id(tmp, len, &id))
            return 0;
        *ret_arg1 = silc_id_dup(&id.u.channel_id, SILC_ID_CHANNEL);
        if (!(*ret_arg1))
            return 0;
        num = 1;
    }
    break;

    case SILC_STATUS_ERR_USER_NOT_ON_CHANNEL:
    case SILC_STATUS_ERR_USER_ON_CHANNEL:
    {
        SilcID id;
        tmp = silc_argument_get_arg_type(args, 2, &len);
        if (!tmp)
            return 0;
        if (silc_id_payload_parse_id(tmp, len, &id))
            return 0;
        *ret_arg1 = silc_id_dup(&id.u.client_id, id.type);
        if (!(*ret_arg1))
            return 0;
        num = 1;
        tmp = silc_argument_get_arg_type(args, 3, &len);
        if (!tmp)
            return num;
        if (silc_id_payload_parse_id(tmp, len, &id))
            return 0;
        *ret_arg2 = silc_id_dup(&id.u.channel_id, id.type);
        if (!(*ret_arg2))
            return num;
        num = 2;
    }
    break;

    default:
        return 0;
        break;
    }

    return num;
}
コード例 #19
0
ファイル: silcattrs.c プロジェクト: TabTwo/silc-client
static unsigned char *
silc_attribute_payload_encode_int(SilcAttribute attribute,
				  SilcAttributeFlags flags,
				  void *object,
				  SilcUInt32 object_size,
				  SilcUInt32 *ret_len)
{
  SilcBuffer tmpbuf = NULL;
  unsigned char tmp[4], *str = NULL, *ret;
  SilcUInt32 len;

  /* Encode according to attribute type */
  if (flags & SILC_ATTRIBUTE_FLAG_VALID) {
    if (!object && !object_size)
      return NULL;

    switch (attribute) {

    case SILC_ATTRIBUTE_USER_INFO:
      {
	SilcVCard vcard = object;
	if (object_size != sizeof(*vcard))
	  return NULL;
	str = silc_vcard_encode(vcard, &object_size);
	if (!str)
	  return NULL;
	object = str;
      }
      break;

    case SILC_ATTRIBUTE_SERVICE:
      {
	SilcAttributeObjService *service = object;
	SilcUInt32 len2;
	if (object_size != sizeof(*service))
	  return NULL;
	len = strlen(service->address);
	len2 = strlen(service->signon);
	tmpbuf = silc_buffer_alloc_size(13 + len + len2);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_INT(service->port),
			   SILC_STR_UI_SHORT(len),
			   SILC_STR_UI_XNSTRING(service->address, len),
			   SILC_STR_UI_CHAR(service->status),
			   SILC_STR_UI_SHORT(len2),
			   SILC_STR_UI_XNSTRING(service->signon, len2),
			   SILC_STR_UI_INT(service->idle),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_STATUS_MOOD:
    case SILC_ATTRIBUTE_PREFERRED_CONTACT:
      {
	SilcUInt32 mask = SILC_PTR_TO_32(object);
	if (object_size != sizeof(SilcUInt32))
	  return NULL;
	SILC_PUT32_MSB(mask, tmp);
	object = tmp;
	object_size = sizeof(SilcUInt32);
      }
      break;

    case SILC_ATTRIBUTE_STATUS_FREETEXT:
    case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
    case SILC_ATTRIBUTE_TIMEZONE:
      {
	unsigned char *string = object;
	str = silc_malloc(2 + object_size);
	if (!str)
	  return NULL;
	SILC_PUT16_MSB(object_size, str);
	memcpy(str + 2, string, object_size);
	object = str;
	object_size += 2;
      }
      break;

    case SILC_ATTRIBUTE_STATUS_MESSAGE:
    case SILC_ATTRIBUTE_EXTENSION:
    case SILC_ATTRIBUTE_USER_ICON:
      {
	SilcMime mime = object;
	if (object_size != sizeof(*mime))
	  return NULL;
	str = silc_mime_encode(mime, &object_size);
	if (!str)
	  return NULL;
	object = str;
      }
      break;

    case SILC_ATTRIBUTE_GEOLOCATION:
      {
	SilcAttributeObjGeo *geo = object;
	SilcUInt32 len1, len2, len3, len4;
	if (object_size != sizeof(*geo))
	  return NULL;
	len1 = (geo->longitude ? strlen(geo->longitude) : 0);
	len2 = (geo->latitude  ? strlen(geo->latitude)  : 0);
	len3 = (geo->altitude  ? strlen(geo->altitude)  : 0);
	len4 = (geo->accuracy  ? strlen(geo->accuracy)  : 0);
	if (len1 + len2 + len3 + len4 == 0)
	  return NULL;
	len = len1 + len2 + len3 + len4;
	tmpbuf = silc_buffer_alloc_size(8 + len);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_SHORT(len1),
			   SILC_STR_UI16_STRING(len1 ? geo->longitude : ""),
			   SILC_STR_UI_SHORT(len2),
			   SILC_STR_UI16_STRING(len2 ? geo->latitude : ""),
			   SILC_STR_UI_SHORT(len3),
			   SILC_STR_UI16_STRING(len3 ? geo->altitude : ""),
			   SILC_STR_UI_SHORT(len4),
			   SILC_STR_UI16_STRING(len4 ? geo->accuracy : ""),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_DEVICE_INFO:
      {
	SilcAttributeObjDevice *dev = object;
	SilcUInt32 len1, len2, len3, len4;
	if (object_size != sizeof(*dev))
	  return NULL;
	len1 = (dev->manufacturer ? strlen(dev->manufacturer) : 0);
	len2 = (dev->version      ? strlen(dev->version)      : 0);
	len3 = (dev->model        ? strlen(dev->model)        : 0);
	len4 = (dev->language     ? strlen(dev->language)     : 0);
	if (len1 + len2 + len3 + len4 == 0)
	  return NULL;
	len = len1 + len2 + len3 + len4;
	tmpbuf = silc_buffer_alloc_size(4 + 8 + len);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_INT(dev->type),
			   SILC_STR_UI_SHORT(len1),
			   SILC_STR_UI16_STRING(len1 ? dev->manufacturer : ""),
			   SILC_STR_UI_SHORT(len2),
			   SILC_STR_UI16_STRING(len2 ? dev->version : ""),
			   SILC_STR_UI_SHORT(len3),
			   SILC_STR_UI16_STRING(len3 ? dev->model : ""),
			   SILC_STR_UI_SHORT(len4),
			   SILC_STR_UI16_STRING(len4 ? dev->language : ""),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_PHONE_NUMBER:
      {
	SilcAttributeObjPN *pn = object;
	if (object_size != sizeof(*pn))
	  return NULL;
	if (!pn->number || strlen(pn->number) < 5)
	  return NULL;
	tmpbuf = silc_buffer_alloc(0);
	if (!tmpbuf)
	  return NULL;
	if (silc_buffer_format(tmpbuf,
			       SILC_STR_UI_INT(pn->format),
			       SILC_STR_UI_SHORT(strlen(pn->number)),
			       SILC_STR_UI16_STRING(pn->number),
			       SILC_STR_END) < 0)
	  return NULL;
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
    case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
      {
	SilcAttributeObjPk *pk = object;
	if (object_size != sizeof(*pk))
	  return NULL;
	len = (pk->type ? strlen(pk->type) : 0);
	tmpbuf = silc_buffer_alloc_size(2 + len + pk->data_len);
	if (!tmpbuf)
	  return NULL;
	silc_buffer_format(tmpbuf,
			   SILC_STR_UI_SHORT(len),
			   SILC_STR_UI16_STRING(pk->type),
			   SILC_STR_UI_XNSTRING(pk->data, pk->data_len),
			   SILC_STR_END);
	object = tmpbuf->data;
	object_size = silc_buffer_len(tmpbuf);
      }
      break;

    case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
    case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
      {
	SilcAttributeObjPk *pk = object;
	if (object_size != sizeof(*pk))
	  return NULL;
	object = pk->data;
	object_size = pk->data_len;
      }
      break;

    default:
      return NULL;
      break;
    }

    ret = silc_memdup(object, object_size);

    if (tmpbuf)
      silc_buffer_free(tmpbuf);
    silc_free(str);

    if (ret_len)
      *ret_len = object_size;

    return ret;
  }

  return NULL;
}
コード例 #20
0
ファイル: silcnet.c プロジェクト: TabTwo/silc-toolkit
SilcBool silc_net_check_local_by_sock(SilcSocket sock, char **hostname,
				      char **ip)
{
  char host[1024];
  int rval, len;

#ifdef HAVE_IPV6
  struct sockaddr_storage local;
  char s[NI_MAXHOST];

  if (hostname)
    *hostname = NULL;
  *ip = NULL;

  SILC_LOG_DEBUG(("Resolving local hostname and IP address"));

  memset(&local, 0, sizeof(local));
  memset(&s, 0, sizeof(s));
  len = sizeof(local);
  rval = getsockname(sock, (struct sockaddr *)&local, &len);
  if (rval < 0)
    return FALSE;

  if (getnameinfo((struct sockaddr *)&local, len, s, sizeof(s), NULL, 0,
		  NI_NUMERICHOST))
    return FALSE;

  *ip = silc_memdup(s, strlen(s));
  if (*ip == NULL)
    return FALSE;
#else
  struct sockaddr_in local;
  char *host_ip;

  if (hostname)
    *hostname = NULL;
  *ip = NULL;

  SILC_LOG_DEBUG(("Resolving local hostname and IP address"));

  memset(&local, 0, sizeof(local));
  len = sizeof(local);
  rval = getsockname(sock, (struct sockaddr *)&local, &len);
  if (rval < 0)
    return FALSE;

  host_ip = inet_ntoa(local.sin_addr);
  if (!host_ip)
    return FALSE;

  *ip = silc_memdup(host_ip, strlen(host_ip));
  if (*ip == NULL)
    return FALSE;
#endif

  /* Do reverse lookup if we want hostname too. */
  if (hostname) {
    /* Get host by address */
    if (!silc_net_gethostbyaddr(*ip, host, sizeof(host)))
      return FALSE;

    *hostname = silc_memdup(host, strlen(host));
    SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));

    /* Reverse */
    if (!silc_net_gethostbyname(*hostname, TRUE, host, sizeof(host)))
      return FALSE;

    if (strcmp(*ip, host))
      return FALSE;
  }

  SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
  return TRUE;
}
コード例 #21
0
ファイル: silcmime.c プロジェクト: TabTwo/silc-server
SilcMime silc_mime_decode(SilcMime mime, const unsigned char *data,
                          SilcUInt32 data_len)
{
    SilcMime m = NULL;
    int i, k;
    char *tmp, *field, *value, *line;

    SILC_LOG_DEBUG(("Parsing MIME message"));

    if (!data)
        return NULL;

    if (!mime) {
        mime = silc_mime_alloc();
        if (!mime)
            return NULL;
        m = mime;
    }

    /* Parse the fields */
    line = tmp = (char *)data;
    for (i = 0; i < data_len; i++) {
        /* Get field line */
        if (data_len - i >= 2 && tmp[i] == '\r' && tmp[i + 1] == '\n') {
            /* Get field */
            field = strchr(line, ':');
            if (!field)
                goto err;
            field = silc_memdup(line, field - line);
            if (!field)
                goto err;

            /* Get value. Remove whitespaces too. */
            value = strchr(line, ':');
            if ((tmp + i) - value < 2)
                goto err;
            value++;
            for (k = 0; k < (tmp + i) - value; k++) {
                if (value[k] == '\r')
                    goto err;
                if (value[k] != ' ' && value[k] != '\t')
                    break;
            }
            value += k;
            if ((tmp + i) - value < 1)
                goto err;
            value = silc_memdup(value, (tmp + i) - value);
            if (!value)
                goto err;

            SILC_LOG_DEBUG(("Header '%s' '%s'", field, value));

            /* Add field and value */
            silc_mime_add_field(mime, field, value);
            silc_free(field);
            silc_free(value);

            /* Mark start of next line */
            line = (tmp + i) + 2;
            i += 2;

            /* Break if this is last header */
            if (data_len - i >= 2 &&
                    tmp[i] == '\r' && tmp[i + 1] == '\n') {
                i += 2;
                break;
            }
        }
    }

    /* Parse multiparts if present */
    field = (char *)silc_mime_get_field(mime, "Content-Type");
    if (field && strstr(field, "multipart")) {
        char b[1024];
        SilcMime p;
        unsigned int len;

        mime->multiparts = silc_dlist_init();
        if (!mime->multiparts)
            goto err;

        /* Get multipart type */
        value = strchr(field, '/');
        if (!value)
            goto err;
        value++;
        if (strchr(field, '"'))
            value++;
        if (!strchr(field, ';'))
            goto err;
        memset(b, 0, sizeof(b));
        len = (unsigned int)(strchr(field, ';') - value);
        if (len > sizeof(b) - 1)
            goto err;
        strncpy(b, value, len);
        if (strchr(b, '"'))
            *strchr(b, '"') = '\0';
        mime->multitype = silc_memdup(b, strlen(b));

        /* Get boundary */
        value = strrchr(field, '=');
        if (value && strlen(value) > 1) {
            value++;

            SILC_LOG_DEBUG(("Boundary '%s'", value));

            memset(b, 0, sizeof(b));
            line = strdup(value);
            if (strrchr(line, '"')) {
                *strrchr(line, '"') = '\0';
                silc_snprintf(b, sizeof(b) - 1, "--%s", line + 1);
                mime->boundary = strdup(line + 1);
            } else {
                silc_snprintf(b, sizeof(b) - 1, "--%s", line);
                mime->boundary = strdup(line);
            }
            silc_free(line);

            for (i = i; i < data_len; i++) {
                /* Get boundary data */
                if (data_len - i >= strlen(b) &&
                        tmp[i] == '-' && tmp[i + 1] == '-') {
                    if (memcmp(tmp + i, b, strlen(b)))
                        continue;

                    i += strlen(b);

                    if (data_len - i >= 4 &&
                            tmp[i    ] == '\r' && tmp[i + 1] == '\n' &&
                            tmp[i + 2] == '\r' && tmp[i + 3] == '\n')
                        i += 4;
                    else if (data_len - i >= 2 &&
                             tmp[i] == '\r' && tmp[i + 1] == '\n')
                        i += 2;
                    else if (data_len - i >= 2 &&
                             tmp[i] == '-' && tmp[i + 1] == '-')
                        break;

                    line = tmp + i;

                    /* Find end of boundary */
                    for (k = i; k < data_len; k++)
                        if (data_len - k >= strlen(b) &&
                                tmp[k] == '-' && tmp[k + 1] == '-')
                            if (!memcmp(tmp + k, b, strlen(b)))
                                break;
                    if (k >= data_len)
                        goto err;

                    /* Remove preceding CRLF */
                    k -= 2;

                    /* Parse the part */
                    p = silc_mime_decode(NULL, line, k - i);
                    if (!p)
                        goto err;

                    silc_dlist_add(mime->multiparts, p);
                    i += (k - i);
                }
            }
        }
    } else {
        /* Get data area.  If we are at the end and we have fields present
           there is no data area present, but, if fields are not present we
           only have data area. */
        if (i >= data_len && !silc_hash_table_count(mime->fields))
            i = 0;
        SILC_LOG_DEBUG(("Data len %d", data_len - i));
        if (data_len - i)
            silc_mime_add_data(mime, tmp + i, data_len - i);
    }

    return mime;

err:
    if (m)
        silc_mime_free(m);
    return NULL;
}
コード例 #22
0
ファイル: command_reply.c プロジェクト: TabTwo/silc-server
static char
silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
{
  SilcServer server = cmd->server;
  unsigned char *id_data, *umodes;
  char *nickname, *username, *realname, *tmp;
  unsigned char *fingerprint;
  SilcID id;
  SilcClientEntry client;
  char global = FALSE;
  char nick[128 + 1], servername[256 + 1], uname[128 + 1];
  SilcUInt32 mode = 0, len, len2, id_len, flen;
  const char *hostname, *ip;

  silc_socket_stream_get_info(silc_packet_stream_get_stream(cmd->sock),
			      NULL, &hostname, &ip, NULL);

  id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len);
  nickname = silc_argument_get_arg_type(cmd->args, 3, &len);
  username = silc_argument_get_arg_type(cmd->args, 4, &len);
  realname = silc_argument_get_arg_type(cmd->args, 5, &len);
  if (!id_data || !nickname || !username || !realname)
    return FALSE;

  tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
  if (tmp)
    SILC_GET32_MSB(mode, tmp);

  if (!silc_id_payload_parse_id(id_data, id_len, &id))
    return FALSE;

  fingerprint = silc_argument_get_arg_type(cmd->args, 9, &flen);

  /* Check if we have this client cached already. */

  client = silc_idlist_find_client_by_id(server->local_list,
					 SILC_ID_GET_ID(id),
					 FALSE, NULL);
  if (!client) {
    client = silc_idlist_find_client_by_id(server->global_list,
					   SILC_ID_GET_ID(id),
					   FALSE, NULL);
    global = TRUE;
  }

  if (!client) {
    /* If router did not find such Client ID in its lists then this must
       be bogus client or some router in the net is buggy. */
    if (server->server_type != SILC_SERVER)
      return FALSE;

    /* Take hostname out of nick string if it includes it. */
    silc_parse_userfqdn(nickname, nick, sizeof(nick), servername,
			sizeof(servername));

    /* We don't have that client anywhere, add it. The client is added
       to global list since server didn't have it in the lists so it must be
       global. This will check for valid nickname and username strings. */
    client = silc_idlist_add_client(server->global_list,
				    strdup(nick), username,
				    strdup(realname),
				    silc_id_dup(SILC_ID_GET_ID(id),
						SILC_ID_CLIENT),
				    silc_packet_get_context(cmd->sock),
				    NULL);
    if (!client) {
      SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
      return FALSE;
    }

    client->data.status |=
      (SILC_IDLIST_STATUS_REGISTERED | SILC_IDLIST_STATUS_RESOLVED);
    client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
    client->mode = mode;
    client->servername = servername[0] ? strdup(servername) : NULL;

    SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
		    server->stat.clients + 1));
    server->stat.clients++;
  } else {
    /* We have the client already, update the data */

    SILC_LOG_DEBUG(("Updating client data"));

    /* Check nickname */
    silc_parse_userfqdn(nickname, nick, sizeof(nick), servername,
			sizeof(servername));
    nickname = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8,
				     128, NULL);
    if (!nickname) {
      SILC_LOG_ERROR(("Malformed nickname '%s' received in WHOIS reply "
		      "from %s",
		      hostname ? hostname : "", nick));
      return FALSE;
    }

    /* Check username */
    silc_parse_userfqdn(username, uname, sizeof(uname), NULL, 0);
    if (!silc_identifier_verify(uname, strlen(uname), SILC_STRING_UTF8, 128)) {
      SILC_LOG_ERROR(("Malformed username '%s' received in WHOIS reply "
		      "from %s",
		      hostname ? hostname : "", tmp));
      return FALSE;
    }

    /* Update entry */
    silc_idcache_update_by_context(global ? server->global_list->clients :
				   server->local_list->clients, client, NULL,
				   nickname, TRUE);

    silc_free(client->nickname);
    silc_free(client->username);
    silc_free(client->userinfo);
    silc_free(client->servername);

    client->nickname = strdup(nick);
    client->username = strdup(username);
    client->userinfo = strdup(realname);
    client->servername = servername[0] ? strdup(servername) : NULL;
    client->mode = mode;
    client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
    client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
  }

  /* Save channel list if it was sent to us */
  if (server->server_type == SILC_SERVER) {
    tmp = silc_argument_get_arg_type(cmd->args, 6, &len);
    umodes = silc_argument_get_arg_type(cmd->args, 10, &len2);
    if (tmp && umodes) {
      SilcBufferStruct channels_buf, umodes_buf;
      silc_buffer_set(&channels_buf, tmp, len);
      silc_buffer_set(&umodes_buf, umodes, len2);
      silc_server_save_user_channels(server, cmd->sock, client, &channels_buf,
				     &umodes_buf);
    } else {
      silc_server_save_user_channels(server, cmd->sock, client, NULL, NULL);
    }
  }

  if (fingerprint && flen == sizeof(client->data.fingerprint))
    memcpy(client->data.fingerprint, fingerprint, flen);

  /* Take Requested Attributes if set. */
  tmp = silc_argument_get_arg_type(cmd->args, 11, &len);
  if (tmp) {
    silc_free(client->attrs);
    client->attrs = silc_memdup(tmp, len);
    client->attrs_len = len;

    /* Try to take public key from attributes if present and we don't have
       the key already.  Do this only on normal server.  Routers do GETKEY
       for all clients anyway. */
    if (server->server_type != SILC_ROUTER && !client->data.public_key) {
      SilcAttributePayload attr;
      SilcAttributeObjPk pk;
      unsigned char f[SILC_HASH_MAXLEN];
      SilcDList attrs = silc_attribute_payload_parse(tmp, len);

      SILC_LOG_DEBUG(("Take client public key from attributes"));

      if (attrs) {
	silc_dlist_start(attrs);
	while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
	  if (silc_attribute_get_attribute(attr) ==
	      SILC_ATTRIBUTE_USER_PUBLIC_KEY) {

	    if (!silc_attribute_get_object(attr, &pk, sizeof(pk)))
	      continue;

	    /* Take only SILC public keys */
	    if (strcmp(pk.type, "silc-rsa")) {
	      silc_free(pk.type);
	      silc_free(pk.data);
	      continue;
	    }

	    /* Verify that the server provided fingerprint matches the key */
	    silc_hash_make(server->sha1hash, pk.data, pk.data_len, f);
	    if (memcmp(f, client->data.fingerprint, sizeof(f))) {
	      silc_free(pk.type);
	      silc_free(pk.data);
	      continue;
	    }

	    /* Save the public key. */
	    if (!silc_pkcs_public_key_alloc(SILC_PKCS_SILC,
					    pk.data, pk.data_len,
					    &client->data.public_key)) {
	      silc_free(pk.type);
	      silc_free(pk.data);
	      continue;
	    }

	    SILC_LOG_DEBUG(("Saved client public key from attributes"));

	    /* Add client's public key to repository */
	    if (!silc_server_get_public_key_by_client(server, client, NULL))
	      silc_skr_add_public_key_simple(server->repository,
					     client->data.public_key,
					     SILC_SKR_USAGE_IDENTIFICATION,
					     client, NULL);

	    silc_free(pk.type);
	    silc_free(pk.data);
	    break;
	  }
	}

	silc_attribute_payload_list_free(attrs);
      }
    }
  }

  return TRUE;
}