xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/midna_adomain.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /*	$NetBSD: midna_adomain.c,v 1.2 2017/02/14 01:16:45 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	midna_adomain 3
6 /* SUMMARY
7 /*	address domain part conversion
8 /* SYNOPSIS
9 /*	#include <midna_adomain.h>
10 /*
11 /*	char	*midna_adomain_to_ascii(
12 /*	VSTRING	*dest,
13 /*	const char *name)
14 /*
15 /*	char	*midna_adomain_to_utf8(
16 /*	VSTRING	*dest,
17 /*	const char *name)
18 /* DESCRIPTION
19 /*	The functions in this module transform the domain portion
20 /*	of an email address between ASCII and UTF-8 form.  Both
21 /*	functions tolerate a missing domain, and both functions
22 /*	return a copy of the input when the domain portion requires
23 /*	no conversion.
24 /*
25 /*	midna_adomain_to_ascii() converts an UTF-8 or ASCII domain
26 /*	portion to ASCII.  The result is a null pointer when
27 /*	conversion fails.  This function verifies that the resulting
28 /*	domain passes valid_hostname().
29 /*
30 /*	midna_adomain_to_utf8() converts an UTF-8 or ASCII domain
31 /*	name to UTF-8.  The result is a null pointer when conversion
32 /*	fails.  This function verifies that the resulting domain,
33 /*	after conversion to ASCII, passes valid_hostname().
34 /* SEE ALSO
35 /*	midna_domain(3), Postfix ASCII/UTF-8 domain name conversion
36 /* DIAGNOSTICS
37 /*	Fatal errors: memory allocation problem.
38 /*	Warnings: conversion error or result validation error.
39 /* LICENSE
40 /* .ad
41 /* .fi
42 /*	The Secure Mailer license must be distributed with this software.
43 /* AUTHOR(S)
44 /*	Wietse Venema
45 /*	IBM T.J. Watson Research
46 /*	P.O. Box 704
47 /*	Yorktown Heights, NY 10598, USA
48 /*--*/
49 
50  /*
51   * System library.
52   */
53 #include <sys_defs.h>
54 #include <string.h>
55 
56 #ifndef NO_EAI
57 #include <unicode/uidna.h>
58 
59  /*
60   * Utility library.
61   */
62 #include <vstring.h>
63 #include <stringops.h>
64 #include <midna_domain.h>
65 
66  /*
67   * Global library.
68   */
69 #include <midna_adomain.h>
70 
71 #define STR(x)	vstring_str(x)
72 
73 /* midna_adomain_to_utf8 - convert address domain portion to UTF8 */
74 
midna_adomain_to_utf8(VSTRING * dest,const char * src)75 char   *midna_adomain_to_utf8(VSTRING *dest, const char *src)
76 {
77     const char *cp;
78     const char *domain_utf8;
79 
80     if ((cp = strrchr(src, '@')) == 0) {
81 	vstring_strcpy(dest, src);
82     } else {
83 	vstring_sprintf(dest, "%*s@", (int) (cp - src), src);
84 	if (*(cp += 1)) {
85 	    if (allascii(cp) && strstr(cp, "--") == 0) {
86 		vstring_strcat(dest, cp);
87 	    } else if ((domain_utf8 = midna_domain_to_utf8(cp)) == 0) {
88 		return (0);
89 	    } else {
90 		vstring_strcat(dest, domain_utf8);
91 	    }
92 	}
93     }
94     return (STR(dest));
95 }
96 
97 /* midna_adomain_to_ascii - convert address domain portion to ASCII */
98 
midna_adomain_to_ascii(VSTRING * dest,const char * src)99 char   *midna_adomain_to_ascii(VSTRING *dest, const char *src)
100 {
101     const char *cp;
102     const char *domain_ascii;
103 
104     if ((cp = strrchr(src, '@')) == 0) {
105 	vstring_strcpy(dest, src);
106     } else {
107 	vstring_sprintf(dest, "%*s@", (int) (cp - src), src);
108 	if (*(cp += 1)) {
109 	    if (allascii(cp)) {
110 		vstring_strcat(dest, cp);
111 	    } else if ((domain_ascii = midna_domain_to_ascii(cp + 1)) == 0) {
112 		return (0);
113 	    } else {
114 		vstring_strcat(dest, domain_ascii);
115 	    }
116 	}
117     }
118     return (STR(dest));
119 }
120 
121 #endif					/* NO_IDNA */
122