/*! * \brief if necessary libraries are present this function converts the input * to utf8 and normalizes it. * \param s The input string * \return Returns a newly allocated zero-terminated string. */ char *normalize( char *s ) { char *buf; #ifdef HAVE_LIBIDN int bufsize, rc; char *utf8; traceLog(LOG_INFO,"Doing stringprep on %s", s); /* stringprep_locale_charset(); */ utf8 = stringprep_locale_to_utf8(s); bufsize = strlen(utf8) * 2; buf = (char *) Malloc ( bufsize * sizeof( char ) ); strcpy(buf,utf8); rc = stringprep (buf, bufsize, 0, stringprep_nameprep); if (rc != STRINGPREP_OK) { traceLog(LOG_INFO,"Stringprep failed with rc %d", rc); Free(buf); buf = utf8; } else Free(utf8); traceLog(LOG_INFO,"result %s", buf); #else buf = Strdup(s); #endif return buf; }
/** * idna_to_unicode_lzlz: * @input: zero-terminated string encoded in the current locale's * character set. * @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 the locale's character * set 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_lzlz (const char *input, char **output, int flags) { char *utf8; int rc; utf8 = stringprep_locale_to_utf8 (input); if (!utf8) return IDNA_ICONV_ERROR; rc = idna_to_unicode_8zlz (utf8, output, flags); free (utf8); return rc; }
int main (void) { char buf[BUFSIZ]; char *p; int rc; size_t i; setlocale (LC_ALL, ""); printf ("Input string encoded as `%s': ", stringprep_locale_charset ()); fflush (stdout); if (!fgets (buf, BUFSIZ, stdin)) perror ("fgets"); buf[strlen (buf) - 1] = '\0'; printf ("Before locale2utf8 (length %ld): ", (long int) strlen (buf)); for (i = 0; i < strlen (buf); i++) printf ("%02x ", buf[i] & 0xFF); printf ("\n"); p = stringprep_locale_to_utf8 (buf); if (p) { strcpy (buf, p); free (p); } else printf ("Could not convert string to UTF-8, continuing anyway...\n"); printf ("Before stringprep (length %ld): ", (long int) strlen (buf)); for (i = 0; i < strlen (buf); i++) printf ("%02x ", buf[i] & 0xFF); printf ("\n"); rc = stringprep (buf, BUFSIZ, 0, stringprep_nameprep); if (rc != STRINGPREP_OK) printf ("Stringprep failed (%d): %s\n", rc, stringprep_strerror (rc)); else { printf ("After stringprep (length %ld): ", (long int) strlen (buf)); for (i = 0; i < strlen (buf); i++) printf ("%02x ", buf[i] & 0xFF); printf ("\n"); } return 0; }
char * getdns_convert_ulabel_to_alabel(const char *ulabel) { #ifdef HAVE_LIBIDN int ret; char *buf; char *prepped; char *prepped2; if (ulabel == NULL) return 0; prepped2 = malloc(BUFSIZ); if(!prepped2) return 0; setlocale(LC_ALL, ""); if ((prepped = stringprep_locale_to_utf8(ulabel)) == 0) { /* convert to utf8 fails, which it can, but continue anyway */ if(strlen(ulabel)+1 > BUFSIZ) { free(prepped2); return 0; } memcpy(prepped2, ulabel, strlen(ulabel)+1); } else { if(strlen(prepped)+1 > BUFSIZ) { free(prepped); free(prepped2); return 0; } memcpy(prepped2, prepped, strlen(prepped)+1); free(prepped); } if ((ret = stringprep(prepped2, BUFSIZ, 0, stringprep_nameprep)) != STRINGPREP_OK) { free(prepped2); return 0; } if ((ret = idna_to_ascii_8z(prepped2, &buf, 0)) != IDNA_SUCCESS) { free(prepped2); return 0; } free(prepped2); return buf; #else return NULL; #endif }
/* Convert a string from the current locale's character set to UTF-8. * <string> .locale_to_utf8 <string> */ static int zlocale_to_utf8(i_ctx_t *i_ctx_p) { os_ptr op = osp; char *input; char *output; int code; check_read_type(*op, t_string); input = ref_to_string(op, imemory, "locale_to_utf8 input"); if (input == 0) return_error(gs_error_VMerror); output = stringprep_locale_to_utf8(input); ifree_string((byte *)input, r_size(op) + 1, "locale_to_utf8 input"); if (output == 0) { /* This function is intended to be used on strings whose * character set is unknown, so it's not an error if the * input contains invalid characters. Just return the input * string unchanged. * * Sadly, EINVAL from stringprep_locale_to_utf8 can mean * either an invalid character set conversion (which we care * about), or an incomplete input string (which we don't). * For now, we ignore EINVAL; the right solution is probably * to not use stringprep_locale_to_utf8, and just call iconv * by hand. */ if (errno == EILSEQ || errno == EINVAL) return 0; /* Other errors (like ENFILE) are real errors, which we * want to return to the user. */ return_error(gs_error_ioerror); } code = string_to_ref(output, op, iimemory, "locale_to_utf8 output"); free(output); if (code < 0) return code; return 0; }
static int niquery_option_subject_name_handler(int index, const char *arg) { static char nigroup_buf[INET6_ADDRSTRLEN + 1 + IFNAMSIZ]; unsigned char *dnptrs[2], **dpp, **lastdnptr; int n; int i; char *name, *p; char *canonname = NULL, *idn = NULL; unsigned char *buf = NULL; size_t namelen; size_t buflen; int dots, fqdn = niquery_options[index].data; MD5_CTX ctxt; __u8 digest[MD5_DIGEST_LENGTH]; #ifdef USE_IDN int rc; #endif if (niquery_set_subject_type(NI_SUBJ_NAME) < 0) return -1; #ifdef USE_IDN name = stringprep_locale_to_utf8(arg); if (!name) { fprintf(stderr, "ping6: IDN support failed.\n"); exit(2); } #else name = strdup(arg); if (!name) goto oomexit; #endif p = strchr(name, SCOPE_DELIMITER); if (p) { *p = '\0'; if (strlen(p + 1) >= IFNAMSIZ) { fprintf(stderr, "ping6: too long scope name.\n"); exit(1); } } #ifdef USE_IDN rc = idna_to_ascii_8z(name, &idn, 0); if (rc) { fprintf(stderr, "ping6: IDN encoding error: %s\n", idna_strerror(rc)); exit(2); } #else idn = strdup(name); if (!idn) goto oomexit; #endif namelen = strlen(idn); canonname = malloc(namelen + 1); if (!canonname) goto oomexit; dots = 0; for (i = 0; i < namelen + 1; i++) { canonname[i] = isupper(idn[i]) ? tolower(idn[i]) : idn[i]; if (idn[i] == '.') dots++; } if (fqdn == 0) { /* guess if hostname is FQDN */ fqdn = dots ? 1 : -1; } buflen = namelen + 3 + 1; /* dn_comp() requrires strlen() + 3, plus non-fqdn indicator. */ buf = malloc(buflen); if (!buf) { fprintf(stderr, "ping6: out of memory.\n"); goto errexit; } dpp = dnptrs; lastdnptr = &dnptrs[ARRAY_SIZE(dnptrs)]; *dpp++ = (unsigned char *)buf; *dpp++ = NULL; n = dn_comp(canonname, (unsigned char *)buf, buflen, dnptrs, lastdnptr); if (n < 0) { fprintf(stderr, "ping6: Inappropriate subject name: %s\n", canonname); goto errexit; } else if (n >= buflen) { fprintf(stderr, "ping6: dn_comp() returned too long result.\n"); goto errexit; } MD5_Init(&ctxt); MD5_Update(&ctxt, buf, buf[0]); MD5_Final(digest, &ctxt); sprintf(nigroup_buf, "ff02::2:%02x%02x:%02x%02x%s%s", digest[0], digest[1], digest[2], digest[3], p ? "%" : "", p ? p + 1 : ""); if (fqdn < 0) buf[n] = 0; free(ni_subject); ni_group = nigroup_buf; ni_subject = buf; ni_subject_len = n + (fqdn < 0); ni_group = nigroup_buf; free(canonname); free(idn); free(name); return 0; oomexit: fprintf(stderr, "ping6: out of memory.\n"); errexit: free(buf); free(canonname); free(idn); free(name); exit(1); }
int main (int argc, char *argv[]) { struct gengetopt_args_info args_info; char readbuf[BUFSIZ]; char *p, *r; uint32_t *q; unsigned cmdn = 0; int rc; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); if (cmdline_parser (argc, argv, &args_info) != 0) return 1; if (!args_info.stringprep_given && !args_info.punycode_encode_given && !args_info.punycode_decode_given && !args_info.idna_to_ascii_given && !args_info.idna_to_unicode_given) args_info.idna_to_ascii_given = 1; if ((args_info.stringprep_given ? 1 : 0) + (args_info.punycode_encode_given ? 1 : 0) + (args_info.punycode_decode_given ? 1 : 0) + (args_info.idna_to_ascii_given ? 1 : 0) + (args_info.idna_to_unicode_given ? 1 : 0) != 1) { fprintf (stderr, _("%s: Only one of -s, -e, -d, -a or -u can be specified.\n"), argv[0]); cmdline_parser_print_help (); return 1; } if (!args_info.quiet_given) fprintf (stderr, "%s %s\n" GREETING, PACKAGE, VERSION); if (args_info.debug_given) fprintf (stderr, _("Charset `%s'.\n"), stringprep_locale_charset ()); if (!args_info.quiet_given && args_info.inputs_num == 0) fprintf (stderr, _("Type each input string on a line by itself, " "terminated by a newline character.\n")); do { if (cmdn < args_info.inputs_num) { strncpy (readbuf, args_info.inputs[cmdn++], BUFSIZ - 1); readbuf[BUFSIZ - 1] = '\0'; } else if (fgets (readbuf, BUFSIZ, stdin) == NULL) { sprintf (readbuf, _("%s: fgets() failed: "), argv[0]); if (!feof (stdin)) perror (readbuf); return 1; } if (readbuf[strlen (readbuf) - 1] == '\n') readbuf[strlen (readbuf) - 1] = '\0'; if (args_info.stringprep_given) { p = stringprep_locale_to_utf8 (readbuf); if (!p) { fprintf (stderr, _("%s: could not convert from %s to UTF-8.\n"), argv[0], stringprep_locale_charset ()); return 1; } q = stringprep_utf8_to_ucs4 (p, -1, NULL); if (!q) { free (p); fprintf (stderr, _("%s: could not convert from UTF-8 to UCS-4.\n"), argv[0]); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; q[i]; i++) fprintf (stderr, _("input[%d] = U+%04x\n"), i, q[i]); } free (q); rc = stringprep_profile (p, &r, args_info.profile_given ? args_info.profile_arg : "Nameprep", 0); free (p); if (rc != STRINGPREP_OK) { fprintf (stderr, _("%s: stringprep_profile() failed with error %d.\n"), argv[0], rc); return 1; } q = stringprep_utf8_to_ucs4 (r, -1, NULL); if (!q) { free (r); fprintf (stderr, _("%s: could not convert from UTF-8 to UCS-4.\n"), argv[0]); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; q[i]; i++) fprintf (stderr, _("output[%d] = U+%04x\n"), i, q[i]); } free (q); p = stringprep_utf8_to_locale (r); free (r); if (!p) { fprintf (stderr, _("%s: could not convert from UTF-8 to %s.\n"), argv[0], stringprep_locale_charset ()); return 1; } fprintf (stdout, "%s\n", p); free (p); } if (args_info.punycode_encode_given) { size_t len, len2; p = stringprep_locale_to_utf8 (readbuf); if (!p) { fprintf (stderr, _("%s: could not convert from %s to UTF-8.\n"), argv[0], stringprep_locale_charset ()); return 1; } q = stringprep_utf8_to_ucs4 (p, -1, &len); free (p); if (!q) { fprintf (stderr, _("%s: could not convert from UTF-8 to UCS-4.\n"), argv[0]); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; i < len; i++) fprintf (stderr, _("input[%d] = U+%04x\n"), i, q[i]); } len2 = BUFSIZ; rc = punycode_encode (len, q, NULL, &len2, readbuf); free (q); if (rc != PUNYCODE_SUCCESS) { fprintf (stderr, _("%s: punycode_encode() failed with error %d.\n"), argv[0], rc); return 1; } readbuf[len2] = '\0'; p = stringprep_utf8_to_locale (readbuf); if (!p) { fprintf (stderr, _("%s: could not convert from UTF-8 to %s.\n"), argv[0], stringprep_locale_charset ()); return 1; } fprintf (stdout, "%s\n", p); free (p); } if (args_info.punycode_decode_given) { size_t len; len = BUFSIZ; q = (uint32_t *) malloc (len * sizeof (q[0])); if (!q) { sprintf (readbuf, _("%s: malloc() failed: "), argv[0]); perror (readbuf); return 1; } rc = punycode_decode (strlen (readbuf), readbuf, &len, q, NULL); if (rc != PUNYCODE_SUCCESS) { free (q); fprintf (stderr, _("%s: punycode_decode() failed with error %d.\n"), argv[0], rc); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; i < len; i++) fprintf (stderr, _("output[%d] = U+%04x\n"), i, q[i]); } q[len] = 0; r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL); free (q); if (!r) { fprintf (stderr, _("%s: could not convert from UCS-4 to UTF-8.\n"), argv[0]); return 1; } p = stringprep_utf8_to_locale (r); free (r); if (!r) { fprintf (stderr, _("%s: could not convert from UTF-8 to %s.\n"), argv[0], stringprep_locale_charset ()); return 1; } fprintf (stdout, "%s\n", p); free (p); } if (args_info.idna_to_ascii_given) { p = stringprep_locale_to_utf8 (readbuf); if (!p) { fprintf (stderr, _("%s: could not convert from %s to UTF-8.\n"), argv[0], stringprep_locale_charset ()); return 1; } q = stringprep_utf8_to_ucs4 (p, -1, NULL); free (p); if (!q) { fprintf (stderr, _("%s: could not convert from UCS-4 to UTF-8.\n"), argv[0]); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; q[i]; i++) fprintf (stderr, _("input[%d] = U+%04x\n"), i, q[i]); } rc = idna_to_ascii_4z (q, &p, (args_info.allow_unassigned_given ? IDNA_ALLOW_UNASSIGNED : 0) | (args_info.usestd3asciirules_given ? IDNA_USE_STD3_ASCII_RULES : 0)); free (q); if (rc != IDNA_SUCCESS) { fprintf (stderr, _("%s: idna_to_ascii_4z() failed " "with error %d.\n"), argv[0], rc); return 1; } #ifdef WITH_TLD if (args_info.tld_flag) { size_t errpos; rc = idna_to_unicode_8z4z (p, &q, (args_info.allow_unassigned_given ? IDNA_ALLOW_UNASSIGNED : 0) | (args_info.usestd3asciirules_given ? IDNA_USE_STD3_ASCII_RULES : 0)); if (rc != IDNA_SUCCESS) { fprintf (stderr, _("%s: TLD idna_to_unicode_8z8z() failed " "with error %d.\n"), argv[0], rc); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; q[i]; i++) fprintf (stderr, _("tld[%d] = U+%04x\n"), i, q[i]); } rc = tld_check_4z (q, &errpos, NULL); if (rc == TLD_INVALID) { fprintf (stderr, _("%s: string rejected by TLD test " "(Unicode position %d)\n"), argv[0], errpos); free (q); return 1; } if (rc != TLD_SUCCESS) { fprintf (stderr, _("%s: tld_check_4z failed with error %d.\n"), argv[0], rc); free (q); return 1; } free (r); } #endif if (args_info.debug_given) { size_t i; for (i = 0; p[i]; i++) fprintf (stderr, _("output[%d] = U+%04x\n"), i, p[i]); } fprintf (stdout, "%s\n", p); free (p); } if (args_info.idna_to_unicode_given) { p = stringprep_locale_to_utf8 (readbuf); if (!p) { fprintf (stderr, _("%s: could not convert from %s to UTF-8.\n"), argv[0], stringprep_locale_charset ()); return 1; } q = stringprep_utf8_to_ucs4 (p, -1, NULL); if (!q) { free (p); fprintf (stderr, _("%s: could not convert from UCS-4 to UTF-8.\n"), argv[0]); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; q[i]; i++) fprintf (stderr, _("input[%d] = U+%04x\n"), i, q[i]); } free (q); rc = idna_to_unicode_8z4z (p, &q, (args_info.allow_unassigned_given ? IDNA_ALLOW_UNASSIGNED : 0) | (args_info.usestd3asciirules_given ? IDNA_USE_STD3_ASCII_RULES : 0)); free (p); if (rc != IDNA_SUCCESS) { fprintf (stderr, _("%s: idna_to_unicode_8z4z() " "failed with error %d.\n"), argv[0], rc); return 1; } if (args_info.debug_given) { size_t i; for (i = 0; q[i]; i++) fprintf (stderr, _("output[%d] = U+%04x\n"), i, q[i]); } #ifdef WITH_TLD if (args_info.tld_flag) { size_t errpos; rc = tld_check_4z (q, &errpos, NULL); if (rc == TLD_INVALID) { fprintf (stderr, _("%s: string rejected by TLD test " "(Unicode position %d)\n"), argv[0], errpos); free (q); return 1; } if (rc != TLD_SUCCESS) { fprintf (stderr, _("%s: tld_check_4z failed with error %d.\n"), argv[0], rc); free (q); return 1; } } #endif r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL); free (q); if (!r) { fprintf (stderr, _("%s: could not convert from UTF-8 to UCS-4.\n"), argv[0]); return 1; } p = stringprep_utf8_to_locale (r); free (r); if (!r) { fprintf (stderr, _("%s: could not convert from UTF-8 to %s.\n"), argv[0], stringprep_locale_charset ()); return 1; } fprintf (stdout, "%s\n", p); free (p); } } while (!feof (stdin) && !ferror (stdin) && (args_info.inputs_num == 0 || cmdn < args_info.inputs_num)); return 0; }
int main (int argc, char *argv[]) { char buf[BUFSIZ]; char *p; uint32_t *r; int rc; size_t errpos, i; printf ("Input domain encoded as `%s': ", stringprep_locale_charset ()); fflush (stdout); fgets (buf, BUFSIZ, stdin); buf[strlen (buf) - 1] = '\0'; printf ("Read string (length %d): ", strlen (buf)); for (i = 0; i < strlen (buf); i++) printf ("%02x ", buf[i] & 0xFF); printf ("\n"); p = stringprep_locale_to_utf8 (buf); if (p) { strcpy (buf, p); free (p); } else printf ("Could not convert string to UTF-8, continuing anyway...\n"); rc = idna_to_ascii_8z (buf, &p, 0); if (rc != IDNA_SUCCESS) { printf ("idna_to_ascii_8z failed (%d): %s\n", rc, idna_strerror (rc)); return 2; } printf ("ToASCII string (length %d): %s\n", strlen (p), p); rc = idna_to_unicode_8z4z (p, &r, 0); free (p); if (rc != IDNA_SUCCESS) { printf ("idna_to_unicode_8z4z failed (%d): %s\n", rc, idna_strerror (rc)); return 2; } printf ("ToUnicode string: "); for (i = 0; r[i]; i++) printf ("U+%04x ", r[i]); printf ("\n"); rc = tld_check_4z (r, &errpos, NULL); free (r); if (rc == TLD_INVALID) { printf ("Domain rejected by TLD check, Unicode position %d\n", errpos); return 1; } else if (rc != TLD_SUCCESS) { printf ("tld_check_4z() failed (%d): %s\n", rc, tld_strerror (rc)); return 2; } printf ("Domain accepted by TLD check\n"); return 0; }