4 #include <internal/windns.h>
9 static BOOL
DnsIntNameContainsDots( LPCWSTR Name
) {
10 return wcschr( Name
, '.' ) ? TRUE
: FALSE
;
13 static BOOL
DnsIntTwoConsecutiveDots( LPCWSTR Name
) {
14 return wcsstr( Name
, L
".." ) ? TRUE
: FALSE
;
17 static BOOL
DnsIntContainsUnderscore( LPCWSTR Name
) {
18 return wcschr( Name
, '_' ) ? TRUE
: FALSE
;
21 /* DnsValidateName *********************
22 * Use some different algorithms to validate the given name as suitable for
25 * Name -- The name to evaluate.
26 * Format -- Format to use:
30 * DnsNameHostnameLabel
34 * ERROR_SUCCESS -- All good
35 * ERROR_INVALID_NAME --
36 * Name greater than 255 chars.
37 * Label greater than 63 chars.
38 * Two consecutive dots, or starts with dot.
39 * Contains a dot, but a Label check was specified.
40 * DNS_ERROR_INVALID_NAME_CHAR
41 * Contains any invalid char: " {|}~[\]^':;<=>?@!"#$%^`()+/,"
42 * Contains an *, except when it is the first label and Wildcard was
44 * DNS_ERROR_NUMERIC_NAME
45 * Set if the name contains only numerics, unless Domain is specified.
46 * DNS_ERROR_NON_RFC_NAME
47 * If the name contains underscore.
48 * If there is an underscore in any position but the first in the SrvRecord
50 * If the name contains a non-ascii character.
53 DNS_STATUS DnsValidateName_W
55 DNS_NAME_FORMAT Format
) {
56 BOOL AllowDot
= FALSE
;
57 BOOL AllowLeadingAst
= FALSE
;
58 BOOL AllowLeadingUnderscore
= FALSE
;
59 BOOL AllowAllDigits
= FALSE
;
60 const WCHAR
*NextLabel
, *CurrentLabel
, *CurrentChar
;
64 AllowAllDigits
= TRUE
;
67 case DnsNameDomainLabel
:
68 AllowAllDigits
= TRUE
;
70 case DnsNameHostnameFull
:
73 case DnsNameHostnameLabel
:
76 AllowLeadingAst
= TRUE
;
79 case DnsNameSrvRecord
:
80 AllowLeadingUnderscore
= TRUE
;
86 /* Preliminary checks */
87 if( Name
[0] == 0 ) return ERROR_INVALID_NAME
; /* XXX arty: Check this */
90 if( wcslen( Name
) > 255 ) {
91 return ERROR_INVALID_NAME
;
94 /* Violations about dots */
95 if( (!AllowDot
&& DnsIntNameContainsDots( Name
)) ||
96 Name
[0] == '.' || DnsIntTwoConsecutiveDots( Name
) )
97 return ERROR_INVALID_NAME
;
99 /* Check component sizes */
102 NextLabel
= CurrentLabel
;
103 while( *NextLabel
&& *NextLabel
!= '.' ) NextLabel
++;
105 if( NextLabel
- CurrentLabel
> 63 )
106 return ERROR_INVALID_NAME
;
108 CurrentLabel
= NextLabel
;
109 } while( *CurrentLabel
);
113 while( *CurrentChar
) {
114 if( wcschr(L
" {|}~[\\]^':;<=>?@!\"#$%^`()+/,",*CurrentChar
) )
115 return DNS_ERROR_INVALID_NAME_CHAR
;
119 if( (!AllowLeadingAst
&& Name
[0] == '*') ||
120 (AllowLeadingAst
&& Name
[0] == '*' && Name
[1] && Name
[1] != '.') )
121 return DNS_ERROR_INVALID_NAME_CHAR
;
123 if( wcschr( Name
+ 1, '*' ) )
124 return DNS_ERROR_INVALID_NAME_CHAR
;
127 while( !AllowAllDigits
&& *CurrentChar
) {
128 if( *CurrentChar
== '.' || (*CurrentChar
>= '0' && *CurrentChar
<= '9') )
129 return DNS_ERROR_NUMERIC_NAME
;
132 if( ((AllowLeadingUnderscore
&& Name
[0] == '_') || Name
[0] != '_') &&
133 !DnsIntContainsUnderscore( Name
+ 1 ) )
134 return DNS_ERROR_NON_RFC_NAME
;
136 return ERROR_SUCCESS
;
139 DNS_STATUS DnsValidateName_UTF8
141 DNS_NAME_FORMAT Format
) {
146 StrLenWc
= mbstowcs( NULL
, Name
, 0 );
147 Buffer
= RtlAllocateHeap( GetProcessHeap(), 0,
148 sizeof( WCHAR
) * (StrLenWc
+ 1) );
149 mbstowcs( Buffer
, Name
, StrLenWc
+ 1 );
150 Status
= DnsValidateName_W( Buffer
, Format
);
151 RtlFreeHeap( GetProcessHeap(), 0, Buffer
);
156 DNS_STATUS DnsValidateName_A
158 DNS_NAME_FORMAT Format
) {
159 return DnsValidateName_UTF8( Name
, Format
);
162 /* DnsNameCompare **********************
163 * Return TRUE if the names are identical.
165 * Name1 & Name2 -- Names.
168 BOOL WINAPI DnsNameCompare_W
173 while( Name1
[offset
] && Name2
[offset
] &&
174 towupper( Name1
[offset
] ) == towupper( Name2
[offset
] ) ) offset
++;
176 (!Name1
[offset
] && !Name2
[offset
]) ||
177 (!Name1
[offset
] && !wcscmp( Name2
+ offset
, L
"." )) ||
178 (!Name2
[offset
] && !wcscmp( Name1
+ offset
, L
"." ));
181 BOOL WINAPI DnsNameCompare_UTF8
186 while( Name1
[offset
] && Name2
[offset
] &&
187 toupper( Name1
[offset
] ) == toupper( Name2
[offset
] ) ) offset
++;
189 (!Name1
[offset
] && !Name2
[offset
]) ||
190 (!Name1
[offset
] && !strcmp( Name2
+ offset
, ".")) ||
191 (!Name2
[offset
] && !strcmp( Name1
+ offset
, "."));
194 BOOL WINAPI DnsNameCompare_A
197 return DnsNameCompare_UTF8( Name1
, Name2
);