Convert the dnsapi stuff to a consistent 4 spaces indentation
[reactos.git] / reactos / dll / win32 / dnsapi / dnsapi / names.c
1 #include "precomp.h"
2
3 #define NDEBUG
4 #include <debug.h>
5
6 static BOOL
7 DnsIntNameContainsDots(LPCWSTR Name)
8 {
9 return wcschr(Name, '.') ? TRUE : FALSE;
10 }
11
12 static BOOL
13 DnsIntTwoConsecutiveDots(LPCWSTR Name)
14 {
15 return wcsstr(Name, L"..") ? TRUE : FALSE;
16 }
17
18 static BOOL
19 DnsIntContainsUnderscore(LPCWSTR Name)
20 {
21 return wcschr(Name, '_') ? TRUE : FALSE;
22 }
23
24 /* DnsValidateName *********************
25 * Use some different algorithms to validate the given name as suitable for
26 * use with DNS.
27 *
28 * Name -- The name to evaluate.
29 * Format -- Format to use:
30 * DnsNameDomain
31 * DnsNameDomainLabel
32 * DnsNameHostnameFull
33 * DnsNameHostnameLabel
34 * DnsNameWildcard
35 * DnsNameSrvRecord
36 * RETURNS:
37 * ERROR_SUCCESS -- All good
38 * ERROR_INVALID_NAME --
39 * Name greater than 255 chars.
40 * Label greater than 63 chars.
41 * Two consecutive dots, or starts with dot.
42 * Contains a dot, but a Label check was specified.
43 * DNS_ERROR_INVALID_NAME_CHAR
44 * Contains any invalid char: " {|}~[\]^':;<=>?@!"#$%^`()+/,"
45 * Contains an *, except when it is the first label and Wildcard was
46 * specified.
47 * DNS_ERROR_NUMERIC_NAME
48 * Set if the name contains only numerics, unless Domain is specified.
49 * DNS_ERROR_NON_RFC_NAME
50 * If the name contains underscore.
51 * If there is an underscore in any position but the first in the SrvRecord
52 * case.
53 * If the name contains a non-ascii character.
54 */
55
56 DNS_STATUS WINAPI
57 DnsValidateName_W(LPCWSTR Name,
58 DNS_NAME_FORMAT Format)
59 {
60 BOOL AllowDot = FALSE;
61 BOOL AllowLeadingAst = FALSE;
62 BOOL AllowLeadingUnderscore = FALSE;
63 BOOL AllowAllDigits = FALSE;
64 const WCHAR *NextLabel, *CurrentLabel, *CurrentChar;
65
66 switch(Format)
67 {
68 case DnsNameDomain:
69 AllowAllDigits = TRUE;
70 AllowDot = TRUE;
71 break;
72
73 case DnsNameDomainLabel:
74 AllowAllDigits = TRUE;
75 break;
76
77 case DnsNameHostnameFull:
78 AllowDot = TRUE;
79 break;
80
81 case DnsNameHostnameLabel:
82 break;
83
84 case DnsNameWildcard:
85 AllowLeadingAst = TRUE;
86 AllowDot = TRUE;
87 break;
88
89 case DnsNameSrvRecord:
90 AllowLeadingUnderscore = TRUE;
91 break;
92
93 default:
94 break;
95 }
96
97 /* Preliminary checks */
98 if(Name[0] == 0)
99 return ERROR_INVALID_NAME; /* XXX arty: Check this */
100
101 /* Name too long */
102 if(wcslen(Name) > 255)
103 return ERROR_INVALID_NAME;
104
105 /* Violations about dots */
106 if((!AllowDot && DnsIntNameContainsDots(Name)) || Name[0] == '.' || DnsIntTwoConsecutiveDots(Name))
107 return ERROR_INVALID_NAME;
108
109 /* Check component sizes */
110 CurrentLabel = Name;
111
112 do
113 {
114 NextLabel = CurrentLabel;
115 while(*NextLabel && *NextLabel != '.')
116 NextLabel++;
117
118 if(NextLabel - CurrentLabel > 63)
119 return ERROR_INVALID_NAME;
120
121 CurrentLabel = NextLabel;
122 } while(*CurrentLabel);
123
124 CurrentChar = Name;
125
126 while(*CurrentChar)
127 {
128 if(wcschr(L" {|}~[\\]^':;<=>?@!\"#$%^`()+/,",*CurrentChar))
129 return DNS_ERROR_INVALID_NAME_CHAR;
130
131 CurrentChar++;
132 }
133
134 if((!AllowLeadingAst && Name[0] == '*') || (AllowLeadingAst && Name[0] == '*' && Name[1] && Name[1] != '.'))
135 return DNS_ERROR_INVALID_NAME_CHAR;
136
137 if(wcschr(Name + 1, '*'))
138 return DNS_ERROR_INVALID_NAME_CHAR;
139
140 CurrentChar = Name;
141
142 while(!AllowAllDigits && *CurrentChar)
143 {
144 if(*CurrentChar == '.' || (*CurrentChar >= '0' && *CurrentChar <= '9'))
145 return DNS_ERROR_NUMERIC_NAME;
146 }
147
148 if(((AllowLeadingUnderscore && Name[0] == '_') || Name[0] != '_') && !DnsIntContainsUnderscore(Name + 1))
149 return DNS_ERROR_NON_RFC_NAME;
150
151 return ERROR_SUCCESS;
152 }
153
154 DNS_STATUS WINAPI
155 DnsValidateName_UTF8(LPCSTR Name,
156 DNS_NAME_FORMAT Format)
157 {
158 PWCHAR Buffer;
159 int StrLenWc;
160 DNS_STATUS Status;
161
162 StrLenWc = mbstowcs(NULL, Name, 0);
163 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(WCHAR) * (StrLenWc + 1));
164 mbstowcs(Buffer, Name, StrLenWc + 1);
165 Status = DnsValidateName_W(Buffer, Format);
166 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
167
168 return Status;
169 }
170
171 DNS_STATUS WINAPI
172 DnsValidateName_A(LPCSTR Name,
173 DNS_NAME_FORMAT Format)
174 {
175 return DnsValidateName_UTF8(Name, Format);
176 }
177
178 /* DnsNameCompare **********************
179 * Return TRUE if the names are identical.
180 *
181 * Name1 & Name2 -- Names.
182 */
183 BOOL WINAPI
184 DnsNameCompare_W(LPWSTR Name1,
185 LPWSTR Name2)
186 {
187 int offset = 0;
188
189 while(Name1[offset] && Name2[offset] && towupper(Name1[offset]) == towupper(Name2[offset]))
190 offset++;
191
192 return
193 (!Name1[offset] && !Name2[offset]) ||
194 (!Name1[offset] && !wcscmp(Name2 + offset, L".")) ||
195 (!Name2[offset] && !wcscmp(Name1 + offset, L"."));
196 }
197
198 BOOL WINAPI
199 DnsNameCompare_UTF8(LPCSTR Name1,
200 LPCSTR Name2)
201 {
202 int offset = 0;
203
204 while(Name1[offset] && Name2[offset] && toupper(Name1[offset]) == toupper(Name2[offset]))
205 offset++;
206
207 return
208 (!Name1[offset] && !Name2[offset]) ||
209 (!Name1[offset] && !strcmp(Name2 + offset, ".")) ||
210 (!Name2[offset] && !strcmp(Name1 + offset, "."));
211 }
212
213 BOOL WINAPI
214 DnsNameCompare_A(LPSTR Name1,
215 LPSTR Name2)
216 {
217 return DnsNameCompare_UTF8(Name1, Name2);
218 }