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 }
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); } }
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; }
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; }
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; }
/** * 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; }
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; }
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; }
/** * 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; }
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); } }