Exemple #1
0
Fichier : utf8.c Projet : Exim/exim
uschar *
string_domain_alabel_to_utf8(const uschar * alabel, uschar ** err)
{
#ifdef SUPPORT_I18N_2008
const uschar * label;
int sep = '.';
gstring * g = NULL;

while (label = string_nextinlist(&alabel, &sep, NULL, 0))
  if (  string_is_alabel(label)
     && !(label = string_localpart_alabel_to_utf8_(label, err))
     )
    return NULL;
  else
    g = string_append_listele(g, '.', label);
return string_from_gstring(g);

#else

uschar * s1, * s;
int rc;

if (  (rc = idna_to_unicode_8z8z(CCS alabel, CSS &s1, IDNA_USE_STD3_ASCII_RULES))
   != IDNA_SUCCESS)
  {
  if (err) *err = US idna_strerror(rc);
  return NULL;
  }
s = string_copy(s1);
free(s1);
return s;
#endif
}
Exemple #2
0
void
doit (void)
{
  int rc;
  char *out = NULL;
  size_t i;

  for (i = 0; i < sizeof (idna) / sizeof (idna[0]); i++)
    {
      rc = idna_to_unicode_8z8z (idna[i].in, &out, 0);
      if (rc != IDNA_SUCCESS)
	fail ("IDNA3[%ld] failed %d\n", i, rc);

      if (debug && rc == IDNA_SUCCESS)
	{
	  printf ("input:        %s\n", idna[i].in);
	  printf ("computed out: %s\n", out);
	  printf ("expected out: %s\n", idna[i].out);
	}

      if (strcmp (out, idna[i].out) != 0)
	fail ("IDNA3[%ld] failed\n", i);
      else if (debug)
	printf ("IDNA3[%ld] success\n", i);

      if (out)
	idn_free (out);
    }
}
Exemple #3
0
int jid_is_my(const char *jid){
int i,at,slash;
int just_digits;
int ret;
char *inbuf,*outbuf;

	if (!jid) return 0;

	just_digits=1;
	at=-1;
	slash=-1;
	/* split into parts, check for numeric username */
	for(i=0;jid[i];i++){
		if (jid[i]=='/' && slash<0) slash=i;
		else if (jid[i]=='@')
			if (!just_digits){
				debug(L_("Non-digits before '@' in jid: %s"),jid);
				return 0;
			}
			else at=i;
		else if (!isdigit(jid[i]) && just_digits) just_digits=0;
	}

	if (slash>=0 && slash<at){
		g_warning(N_("slash<at (%i<%i) in %s"),slash,at,jid);
		return 0;
	}

	if ((slash<0 && strlen(jid+at+1)>1023) || slash-at-1>1023){
		g_warning(N_("JID domain too long"));
		return 0;
	}

	if (slash<0)
		inbuf=g_strdup(jid+at+1);
	else
		inbuf=g_strndup(jid+at+1,slash-at-1);

	ret=idna_to_unicode_8z8z(inbuf,&outbuf,IDNA_ALLOW_UNASSIGNED);

	if (ret!=IDNA_SUCCESS){
		g_warning(N_("JID domain doesn't pass ToUnicode"));
		ret=0;
	}
	else{
		ret=!strcmp(outbuf,my_name);
		if (!ret){
			debug(L_("Bad hostname (%s) in JID: %s"),outbuf,jid);
		}
	}

	g_free(inbuf);
	g_free(outbuf);

	return ret;
}
Exemple #4
0
static int mutt_idna_to_local (const char *in, char **out, int flags)
{
  *out = NULL;

  if (!option (OPTUSEIDN))
    goto notrans;

  if (!in)
    goto notrans;

  /* Is this the right function?  Interesting effects with some bad identifiers! */
  if (idna_to_unicode_8z8z (in, out, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS)
    goto notrans;

  /* we don't want charset-hook effects, so we set flags to 0 */
  if (mutt_convert_string (out, "utf-8", Charset, 0) == -1)
    goto notrans;

  /* 
   * make sure that we can convert back and come out with the same
   * domain name. 
   */
  
  if ((flags & MI_MAY_BE_IRREVERSIBLE) == 0)
  {
    int irrev = 0;
    char *t2 = NULL;
    char *tmp = safe_strdup (*out);

    /* we don't want charset-hook effects, so we set flags to 0 */
    if (mutt_convert_string (&tmp, Charset, "utf-8", 0) == -1)
      irrev = 1;
    if (!irrev && idna_to_ascii_8z (tmp, &t2, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS)
      irrev = 1;
    if (!irrev && ascii_strcasecmp (t2, in))
    {
      dprint (1, (debugfile, "mutt_idna_to_local: Not reversible. in = '%s', t2 = '%s'.\n",
		  in, t2));
      irrev = 1;
    }
    
    FREE (&t2);
    FREE (&tmp);

    if (irrev)
      goto notrans;
  }

  return 0;
  
 notrans:
  FREE (out);		/* __FREE_CHECKED__ */
  *out = safe_strdup (in);
  return 1;
}
Exemple #5
0
char *
getdns_convert_alabel_to_ulabel(const char *alabel)
{
    int  ret;              /* just in case we might want to use it someday */
    char *buf;

    if (alabel == NULL)
        return 0;
    if ((ret = idna_to_unicode_8z8z(alabel, &buf, 0)) != IDNA_SUCCESS)  {
        return NULL;
    }
    return buf;
}
Exemple #6
0
/**
 * idna_to_unicode_8zlz:
 * @input: zero-terminated UTF-8 string.
 * @output: pointer to newly allocated output string encoded in the
 *   current locale's character set.
 * @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
 *
 * Convert possibly ACE encoded domain name in UTF-8 format into a
 * string encoded in the current locale's character set.  The domain
 * name may contain several labels, separated by dots.  The output
 * buffer must be deallocated by the caller.
 *
 * Return value: Returns IDNA_SUCCESS on success, or error code.
 **/
int
idna_to_unicode_8zlz (const char *input, char **output, int flags)
{
  char *utf8;
  int rc;

  rc = idna_to_unicode_8z8z (input, &utf8, flags);
  *output = stringprep_utf8_to_locale (utf8);
  free (utf8);

  if (!*output)
    return IDNA_ICONV_ERROR;

  return rc;
}
uschar *
string_domain_alabel_to_utf8(const uschar * alabel, uschar ** err)
{
uschar * s1;
uschar * s;
int rc;

if (  (rc = idna_to_unicode_8z8z(CCS alabel, CSS &s1, IDNA_USE_STD3_ASCII_RULES))
   != IDNA_SUCCESS)
  {
  if (err) *err = US idna_strerror(rc);
  return NULL;
  }
s = string_copy(s1);
free(s1);
return s;
}
Exemple #8
0
int jid_is_me(const char *jid){
int i,slash;
int ret;
char *inbuf,*outbuf;

	if (!jid) return 0;

	slash=-1;
	for(i=0;jid[i];i++){
		if (jid[i]=='/' && slash<0) slash=i;
		else if (jid[i]=='@') return 0;
	}

	if ((slash<0 && strlen(jid)>1023) || slash>1023){
		g_warning(N_("JID domain too long"));
		return 0;
	}

	if (slash<0)
		inbuf=g_strdup(jid);
	else
		inbuf=g_strndup(jid,slash);

	ret=idna_to_unicode_8z8z(inbuf,&outbuf,IDNA_ALLOW_UNASSIGNED);

	if (ret!=IDNA_SUCCESS){
		g_warning(N_("JID domain doesn't pass ToUnicode"));
		ret=0;
	}
	else{
		ret=!strcmp(outbuf,my_name);
	}

	g_free(inbuf);
	g_free(outbuf);

	return ret;
}
Exemple #9
0
static char *udomainutf82(const char *c)
{
	const char *d;
	char *ud;
	char *s;

	d=strchr(c, '@');

	if (!d)
		return courier_strdup(c);

	++d;
	if (idna_to_unicode_8z8z(d, &s, 0) != IDNA_SUCCESS)
	{
		return courier_strdup(c);
	}

	ud=courier_malloc((d-c+1)+strlen(s));

	memcpy(ud, c, d-c);
	strcpy(ud+(d-c), s);
	free(s);
	return ud;
}
Exemple #10
0
/**
 * Parse name inside of a DNS query or record.
 *
 * @param udp_payload entire UDP payload
 * @param udp_payload_length length of @a udp_payload
 * @param off pointer to the offset of the name to parse in the udp_payload (to be
 *                    incremented by the size of the name)
 * @param depth current depth of our recursion (to prevent stack overflow)
 * @return name as 0-terminated C string on success, NULL if the payload is malformed
 */
static char *
parse_name (const char *udp_payload,
	    size_t udp_payload_length,
	    size_t *off,
	    unsigned int depth)
{
  const uint8_t *input = (const uint8_t *) udp_payload;
  char *ret;
  char *tmp;
  char *xstr;
  uint8_t len;
  size_t xoff;
  char *utf8;
  Idna_rc rc;

  ret = GNUNET_strdup ("");
  while (1)
  {
    if (*off >= udp_payload_length)
    {
      GNUNET_break_op (0);
      goto error;
    }
    len = input[*off];
    if (0 == len)
    {
      (*off)++;
      break;
    }
    if (len < 64)
    {
      if (*off + 1 + len > udp_payload_length)
      {
	GNUNET_break_op (0);
	goto error;
      }
      GNUNET_asprintf (&tmp,
		       "%.*s",
		       (int) len,
		       &udp_payload[*off + 1]);
      if (IDNA_SUCCESS !=
	  (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED)))
      {
	GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		    _("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
		    tmp,
		    idna_strerror (rc));
	GNUNET_free (tmp);
	GNUNET_asprintf (&tmp,
			 "%s%.*s.",
			 ret,
			 (int) len,
			 &udp_payload[*off + 1]);
      }
      else
      {
	GNUNET_free (tmp);
	GNUNET_asprintf (&tmp,
			 "%s%s.",
			 ret,
			 utf8);
#if WINDOWS
	idn_free (utf8);
#else
	free (utf8);
#endif
      }
      GNUNET_free (ret);
      ret = tmp;
      *off += 1 + len;
    }
    else if ((64 | 128) == (len & (64 | 128)) )
    {
      if (depth > 32)
      {
	GNUNET_break_op (0);
	goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */
      }
      /* pointer to string */
      if (*off + 1 > udp_payload_length)
      {
	GNUNET_break_op (0);
	goto error;
      }
      xoff = ((len - (64 | 128)) << 8) + input[*off+1];
      xstr = parse_name (udp_payload,
			 udp_payload_length,
			 &xoff,
			 depth + 1);
      if (NULL == xstr)
      {
	GNUNET_break_op (0);
	goto error;
      }
      GNUNET_asprintf (&tmp,
		       "%s%s.",
		       ret,
		       xstr);
      GNUNET_free (ret);
      GNUNET_free (xstr);
      ret = tmp;
      if (strlen (ret) > udp_payload_length)
      {
	GNUNET_break_op (0);
	goto error; /* we are looping (building an infinite string) */
      }
      *off += 2;
      /* pointers always terminate names */
      break;
    }
    else
    {
      /* neither pointer nor inline string, not supported... */
      GNUNET_break_op (0);
      goto error;
    }
  }
  if (0 < strlen(ret))
    ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */
  return ret;
 error:
  GNUNET_break_op (0);
  GNUNET_free (ret);
  return NULL;
}
Exemple #11
0
char * jid_normalized(const char *jid,int full){
int i,at,slash,ret;
char node[1024],domain[1024],resource[1024];
char *domainbuf;

	if (!jid) return NULL;

	slash=-1;
	at=-1;
	/* split into parts */
	for(i=0;jid[i];i++){
		if (jid[i]=='@' && at<0) at=i;
		if (jid[i]=='/' && slash<0) slash=i;
	}

	if (slash>=0 && slash<at){
		g_warning(N_("slash<at (%i<%i) in %s"),slash,at,jid);
		return NULL;
	}
	if (slash==at+1){
		g_warning(N_("empty domain in %s"),jid);
		return NULL;
	}

	/* node */
	if (at>0){
		if (at>1023){
			g_warning(N_("node too long in %s"),jid);
			return NULL;
		}
		memcpy(node,jid,at);
		node[at]='\000';
	}
	else node[0]='\000';

	/* domain */
	if (slash>0){
		if (slash-at>1024){
			g_warning(N_("domain too long in %s"),jid);
			return NULL;
		}
		memcpy(domain,jid+at+1,slash-at-1);
		domain[slash-at-1]='\000';
	}
	else{
		if (strlen(jid+at+1)>1023){
			g_warning(N_("domain too long in %s"),jid);
			return NULL;
		}
		strcpy(domain,jid+at+1);
	}

	/* resource */
	if (slash>0){
		if (strlen(jid+slash+1)>1023){
			g_warning(N_("resource too long in %s"),jid);
			return NULL;
		}
		strcpy(resource,jid+slash+1);
	}
	else resource[0]='\000';

	if (node[0]){
		ret=stringprep_xmpp_nodeprep(node,1024);
		if (ret!=0){
			g_warning(N_("bad node: %s"),node);
			return NULL;
		}
	}
	if (resource[0]){
		ret=stringprep_xmpp_resourceprep(resource,1024);
		if (ret!=0){
			g_warning(N_("bad node: %s"),resource);
			return NULL;
		}
	}
	ret=idna_to_unicode_8z8z(domain,&domainbuf,IDNA_ALLOW_UNASSIGNED);
	if (ret!=IDNA_SUCCESS){
		g_warning(N_("bad domain: %s"),domain);
		return NULL;
	}
	strcpy(domain,domainbuf);
	g_free(domainbuf);

	if (!full || !resource[0]){
		if (node[0])
			return g_strconcat(node,"@",domain,NULL);
		else
			return g_strdup(domain);
	}
	else{
		if (node[0])
			return g_strconcat(node,"@",domain,"/",resource,NULL);
		else
			return g_strconcat(domain,"/",resource,NULL);
	}
}