]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSShared/dnsextd_parser.y
mDNSResponder-212.1.tar.gz
[apple/mdnsresponder.git] / mDNSShared / dnsextd_parser.y
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16
17 Change History (most recent first):
18
19 $Log: dnsextd_parser.y,v $
20 Revision 1.9 2009/01/11 03:20:06 mkrochma
21 <rdar://problem/5797526> Fixes from Igor Seleznev to get mdnsd working on Solaris
22
23 Revision 1.8 2007/03/21 19:47:50 cheshire
24 <rdar://problem/4789463> Leak: On error path in ParseConfig
25
26 Revision 1.7 2007/01/17 17:38:13 cheshire
27 Need to include stdlib.h for malloc/free
28
29 Revision 1.6 2006/12/22 20:59:51 cheshire
30 <rdar://problem/4742742> Read *all* DNS keys from keychain,
31 not just key for the system-wide default registration domain
32
33 Revision 1.5 2006/10/20 05:47:09 herscher
34 Set the DNSZone pointer to NULL in ParseConfig() before parsing the configuration file.
35
36 Revision 1.4 2006/08/16 00:35:39 mkrochma
37 <rdar://problem/4386944> Get rid of NotAnInteger references
38
39 Revision 1.3 2006/08/14 23:24:56 cheshire
40 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
41
42 Revision 1.2 2006/07/14 02:03:37 cheshire
43 <rdar://problem/4472013> Add Private DNS server functionality to dnsextd
44 private_port and llq_port should use htons, not htonl
45
46 Revision 1.1 2006/07/06 00:09:05 cheshire
47 <rdar://problem/4472013> Add Private DNS server functionality to dnsextd
48
49 */
50
51 %{
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include "mDNSEmbeddedAPI.h"
56 #include "DebugServices.h"
57 #include "dnsextd.h"
58
59 void yyerror( const char* error );
60 int yylex(void);
61
62
63 typedef struct StringListElem
64 {
65 char * string;
66 struct StringListElem * next;
67 } StringListElem;
68
69
70 typedef struct OptionsInfo
71 {
72 char server_address[ 256 ];
73 int server_port;
74 char source_address[ 256 ];
75 int source_port;
76 int private_port;
77 int llq_port;
78 } OptionsInfo;
79
80
81 typedef struct ZoneInfo
82 {
83 char name[ 256 ];
84 char certificate_name[ 256 ];
85 char allow_clients_file[ 256 ];
86 char allow_clients[ 256 ];
87 char key[ 256 ];
88 } ZoneInfo;
89
90
91 typedef struct KeySpec
92 {
93 char name[ 256 ];
94 char algorithm[ 256 ];
95 char secret[ 256 ];
96 struct KeySpec * next;
97 } KeySpec;
98
99
100 typedef struct ZoneSpec
101 {
102 char name[ 256 ];
103 DNSZoneSpecType type;
104 StringListElem * allowUpdate;
105 StringListElem * allowQuery;
106 char key[ 256 ];
107 struct ZoneSpec * next;
108 } ZoneSpec;
109
110
111 static StringListElem * g_stringList = NULL;
112 static KeySpec * g_keys;
113 static ZoneSpec * g_zones;
114 static ZoneSpec g_zoneSpec;
115 static const char * g_filename;
116
117 #define YYPARSE_PARAM context
118
119 void
120 SetupOptions
121 (
122 OptionsInfo * info,
123 void * context
124 );
125
126 %}
127
128 %union
129 {
130 int number;
131 char * string;
132 }
133
134 %token OPTIONS
135 %token LISTEN_ON
136 %token NAMESERVER
137 %token PORT
138 %token ADDRESS
139 %token LLQ
140 %token PUBLIC
141 %token PRIVATE
142 %token ALLOWUPDATE
143 %token ALLOWQUERY
144 %token KEY
145 %token ALGORITHM
146 %token SECRET
147 %token ISSUER
148 %token SERIAL
149 %token ZONE
150 %token TYPE
151 %token ALLOW
152 %token OBRACE
153 %token EBRACE
154 %token SEMICOLON
155 %token IN
156 %token <string> DOTTED_DECIMAL_ADDRESS
157 %token <string> WILDCARD
158 %token <string> DOMAINNAME
159 %token <string> HOSTNAME
160 %token <string> QUOTEDSTRING
161 %token <number> NUMBER
162
163 %type <string> addressstatement
164 %type <string> networkaddress
165
166 %%
167
168 commands:
169 |
170 commands command SEMICOLON
171 ;
172
173
174 command:
175 options_set
176 |
177 zone_set
178 |
179 key_set
180 ;
181
182
183 options_set:
184 OPTIONS optionscontent
185 {
186 // SetupOptions( &g_optionsInfo, context );
187 }
188 ;
189
190 optionscontent:
191 OBRACE optionsstatements EBRACE
192 ;
193
194 optionsstatements:
195 |
196 optionsstatements optionsstatement SEMICOLON
197 ;
198
199
200 optionsstatement:
201 statements
202 |
203 LISTEN_ON addresscontent
204 {
205 }
206 |
207 LISTEN_ON PORT NUMBER addresscontent
208 {
209 }
210 |
211 NAMESERVER ADDRESS networkaddress
212 {
213 }
214 |
215 NAMESERVER ADDRESS networkaddress PORT NUMBER
216 {
217 }
218 |
219 PRIVATE PORT NUMBER
220 {
221 ( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( NUMBER );
222 }
223 |
224 LLQ PORT NUMBER
225 {
226 ( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( NUMBER );
227 }
228 ;
229
230 key_set:
231 KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE
232 {
233 KeySpec * keySpec;
234
235 keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) );
236
237 if ( !keySpec )
238 {
239 LogMsg("ERROR: memory allocation failure");
240 YYABORT;
241 }
242
243 strncpy( keySpec->name, $2, sizeof( keySpec->name ) );
244 strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) );
245
246 keySpec->next = g_keys;
247 g_keys = keySpec;
248 }
249 ;
250
251 zone_set:
252 ZONE QUOTEDSTRING zonecontent
253 {
254 ZoneSpec * zoneSpec;
255
256 zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
257
258 if ( !zoneSpec )
259 {
260 LogMsg("ERROR: memory allocation failure");
261 YYABORT;
262 }
263
264 strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
265 zoneSpec->type = g_zoneSpec.type;
266 strcpy( zoneSpec->key, g_zoneSpec.key );
267 zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
268 zoneSpec->allowQuery = g_zoneSpec.allowQuery;
269
270 zoneSpec->next = g_zones;
271 g_zones = zoneSpec;
272 }
273 |
274 ZONE QUOTEDSTRING IN zonecontent
275 {
276 ZoneSpec * zoneSpec;
277
278 zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
279
280 if ( !zoneSpec )
281 {
282 LogMsg("ERROR: memory allocation failure");
283 YYABORT;
284 }
285
286 strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
287 zoneSpec->type = g_zoneSpec.type;
288 strcpy( zoneSpec->key, g_zoneSpec.key );
289 zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
290 zoneSpec->allowQuery = g_zoneSpec.allowQuery;
291
292 zoneSpec->next = g_zones;
293 g_zones = zoneSpec;
294 }
295 ;
296
297 zonecontent:
298 OBRACE zonestatements EBRACE
299
300 zonestatements:
301 |
302 zonestatements zonestatement SEMICOLON
303 ;
304
305 zonestatement:
306 TYPE PUBLIC
307 {
308 g_zoneSpec.type = kDNSZonePublic;
309 }
310 |
311 TYPE PRIVATE
312 {
313 g_zoneSpec.type = kDNSZonePrivate;
314 }
315 |
316 ALLOWUPDATE keycontent
317 {
318 g_zoneSpec.allowUpdate = g_stringList;
319 g_stringList = NULL;
320 }
321 |
322 ALLOWQUERY keycontent
323 {
324 g_zoneSpec.allowQuery = g_stringList;
325 g_stringList = NULL;
326 }
327 ;
328
329 addresscontent:
330 OBRACE addressstatements EBRACE
331 {
332 }
333
334 addressstatements:
335 |
336 addressstatements addressstatement SEMICOLON
337 {
338 }
339 ;
340
341 addressstatement:
342 DOTTED_DECIMAL_ADDRESS
343 {
344 }
345 ;
346
347
348 keycontent:
349 OBRACE keystatements EBRACE
350 {
351 }
352
353 keystatements:
354 |
355 keystatements keystatement SEMICOLON
356 {
357 }
358 ;
359
360 keystatement:
361 KEY DOMAINNAME
362 {
363 StringListElem * elem;
364
365 elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
366
367 if ( !elem )
368 {
369 LogMsg("ERROR: memory allocation failure");
370 YYABORT;
371 }
372
373 elem->string = $2;
374
375 elem->next = g_stringList;
376 g_stringList = elem;
377 }
378 ;
379
380
381 networkaddress:
382 DOTTED_DECIMAL_ADDRESS
383 |
384 HOSTNAME
385 |
386 WILDCARD
387 ;
388
389 block:
390 OBRACE zonestatements EBRACE SEMICOLON
391 ;
392
393 statements:
394 |
395 statements statement
396 ;
397
398 statement:
399 block
400 {
401 $<string>$ = NULL;
402 }
403 |
404 QUOTEDSTRING
405 {
406 $<string>$ = $1;
407 }
408 %%
409
410 int yywrap(void);
411
412 extern int yylineno;
413
414 void yyerror( const char *str )
415 {
416 fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
417 }
418
419 int yywrap()
420 {
421 return 1;
422 }
423
424
425 int
426 ParseConfig
427 (
428 DaemonInfo * d,
429 const char * file
430 )
431 {
432 extern FILE * yyin;
433 DNSZone * zone;
434 DomainAuthInfo * key;
435 KeySpec * keySpec;
436 ZoneSpec * zoneSpec;
437 int err = 0;
438
439 g_filename = file;
440
441 // Tear down the current zone specifiers
442
443 zone = d->zones;
444
445 while ( zone )
446 {
447 DNSZone * next = zone->next;
448
449 key = zone->updateKeys;
450
451 while ( key )
452 {
453 DomainAuthInfo * nextKey = key->next;
454
455 free( key );
456
457 key = nextKey;
458 }
459
460 key = zone->queryKeys;
461
462 while ( key )
463 {
464 DomainAuthInfo * nextKey = key->next;
465
466 free( key );
467
468 key = nextKey;
469 }
470
471 free( zone );
472
473 zone = next;
474 }
475
476 d->zones = NULL;
477
478 yyin = fopen( file, "r" );
479 require_action( yyin, exit, err = 0 );
480
481 err = yyparse( ( void* ) d );
482 require_action( !err, exit, err = 1 );
483
484 for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next )
485 {
486 StringListElem * elem;
487 mDNSu8 * ok;
488
489 zone = ( DNSZone* ) malloc( sizeof( DNSZone ) );
490 require_action( zone, exit, err = 1 );
491 memset( zone, 0, sizeof( DNSZone ) );
492
493 zone->next = d->zones;
494 d->zones = zone;
495
496 // Fill in the domainname
497
498 ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name );
499 require_action( ok, exit, err = 1 );
500
501 // Fill in the type
502
503 zone->type = zoneSpec->type;
504
505 // Fill in the allow-update keys
506
507 for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next )
508 {
509 mDNSBool found = mDNSfalse;
510
511 for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
512 {
513 if ( strcmp( elem->string, keySpec->name ) == 0 )
514 {
515 DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) );
516 mDNSs32 keylen;
517 require_action( authInfo, exit, err = 1 );
518 memset( authInfo, 0, sizeof( DomainAuthInfo ) );
519
520 ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
521 if (!ok) { free(authInfo); err = 1; goto exit; }
522
523 keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
524 if (keylen < 0) { free(authInfo); err = 1; goto exit; }
525
526 authInfo->next = zone->updateKeys;
527 zone->updateKeys = authInfo;
528
529 found = mDNStrue;
530
531 break;
532 }
533 }
534
535 // Log this
536 require_action( found, exit, err = 1 );
537 }
538
539 // Fill in the allow-query keys
540
541 for ( elem = zoneSpec->allowQuery; elem; elem = elem->next )
542 {
543 mDNSBool found = mDNSfalse;
544
545 for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
546 {
547 if ( strcmp( elem->string, keySpec->name ) == 0 )
548 {
549 DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) );
550 mDNSs32 keylen;
551 require_action( authInfo, exit, err = 1 );
552 memset( authInfo, 0, sizeof( DomainAuthInfo ) );
553
554 ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
555 if (!ok) { free(authInfo); err = 1; goto exit; }
556
557 keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
558 if (keylen < 0) { free(authInfo); err = 1; goto exit; }
559
560 authInfo->next = zone->queryKeys;
561 zone->queryKeys = authInfo;
562
563 found = mDNStrue;
564
565 break;
566 }
567 }
568
569 // Log this
570 require_action( found, exit, err = 1 );
571 }
572 }
573
574 exit:
575
576 return err;
577 }
578
579
580 void
581 SetupOptions
582 (
583 OptionsInfo * info,
584 void * context
585 )
586 {
587 DaemonInfo * d = ( DaemonInfo* ) context;
588
589 if ( strlen( info->source_address ) )
590 {
591 inet_pton( AF_INET, info->source_address, &d->addr.sin_addr );
592 }
593
594 if ( info->source_port )
595 {
596 d->addr.sin_port = htons( ( mDNSu16 ) info->source_port );
597 }
598
599 if ( strlen( info->server_address ) )
600 {
601 inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr );
602 }
603
604 if ( info->server_port )
605 {
606 d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port );
607 }
608
609 if ( info->private_port )
610 {
611 d->private_port = mDNSOpaque16fromIntVal( info->private_port );
612 }
613
614 if ( info->llq_port )
615 {
616 d->llq_port = mDNSOpaque16fromIntVal( info->llq_port );
617 }
618 }