1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 Change History (most recent first):
19 $Log: dnsextd_parser.y,v $
20 Revision 1.8 2007/03/21 19:47:50 cheshire
21 <rdar://problem/4789463> Leak: On error path in ParseConfig
23 Revision 1.7 2007/01/17 17:38:13 cheshire
24 Need to include stdlib.h for malloc/free
26 Revision 1.6 2006/12/22 20:59:51 cheshire
27 <rdar://problem/4742742> Read *all* DNS keys from keychain,
28 not just key for the system-wide default registration domain
30 Revision 1.5 2006/10/20 05:47:09 herscher
31 Set the DNSZone pointer to NULL in ParseConfig() before parsing the configuration file.
33 Revision 1.4 2006/08/16 00:35:39 mkrochma
34 <rdar://problem/4386944> Get rid of NotAnInteger references
36 Revision 1.3 2006/08/14 23:24:56 cheshire
37 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
39 Revision 1.2 2006/07/14 02:03:37 cheshire
40 <rdar://problem/4472013> Add Private DNS server functionality to dnsextd
41 private_port and llq_port should use htons, not htonl
43 Revision 1.1 2006/07/06 00:09:05 cheshire
44 <rdar://problem/4472013> Add Private DNS server functionality to dnsextd
52 #include <mDNSEmbeddedAPI.h>
53 #include <DebugServices.h>
56 void yyerror( const char* error );
60 typedef struct StringListElem
63 struct StringListElem * next;
67 typedef struct OptionsInfo
69 char server_address[ 256 ];
71 char source_address[ 256 ];
78 typedef struct ZoneInfo
81 char certificate_name[ 256 ];
82 char allow_clients_file[ 256 ];
83 char allow_clients[ 256 ];
88 typedef struct KeySpec
91 char algorithm[ 256 ];
93 struct KeySpec * next;
97 typedef struct ZoneSpec
100 DNSZoneSpecType type;
101 StringListElem * allowUpdate;
102 StringListElem * allowQuery;
104 struct ZoneSpec * next;
108 static StringListElem * g_stringList = NULL;
109 static KeySpec * g_keys;
110 static ZoneSpec * g_zones;
111 static ZoneSpec g_zoneSpec;
112 static const char * g_filename;
114 #define YYPARSE_PARAM context
153 %token <string> DOTTED_DECIMAL_ADDRESS
154 %token <string> WILDCARD
155 %token <string> DOMAINNAME
156 %token <string> HOSTNAME
157 %token <string> QUOTEDSTRING
158 %token <number> NUMBER
160 %type <string> addressstatement
161 %type <string> networkaddress
167 commands command SEMICOLON
181 OPTIONS optionscontent
183 // SetupOptions( &g_optionsInfo, context );
188 OBRACE optionsstatements EBRACE
193 optionsstatements optionsstatement SEMICOLON
200 LISTEN_ON addresscontent
204 LISTEN_ON PORT NUMBER addresscontent
208 NAMESERVER ADDRESS networkaddress
212 NAMESERVER ADDRESS networkaddress PORT NUMBER
218 ( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( NUMBER );
223 ( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( NUMBER );
228 KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE
232 keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) );
236 LogMsg("ERROR: memory allocation failure");
240 strncpy( keySpec->name, $2, sizeof( keySpec->name ) );
241 strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) );
243 keySpec->next = g_keys;
249 ZONE QUOTEDSTRING zonecontent
253 zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
257 LogMsg("ERROR: memory allocation failure");
261 strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
262 zoneSpec->type = g_zoneSpec.type;
263 strcpy( zoneSpec->key, g_zoneSpec.key );
264 zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
265 zoneSpec->allowQuery = g_zoneSpec.allowQuery;
267 zoneSpec->next = g_zones;
271 ZONE QUOTEDSTRING IN zonecontent
275 zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
279 LogMsg("ERROR: memory allocation failure");
283 strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
284 zoneSpec->type = g_zoneSpec.type;
285 strcpy( zoneSpec->key, g_zoneSpec.key );
286 zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
287 zoneSpec->allowQuery = g_zoneSpec.allowQuery;
289 zoneSpec->next = g_zones;
295 OBRACE zonestatements EBRACE
299 zonestatements zonestatement SEMICOLON
305 g_zoneSpec.type = kDNSZonePublic;
310 g_zoneSpec.type = kDNSZonePrivate;
313 ALLOWUPDATE keycontent
315 g_zoneSpec.allowUpdate = g_stringList;
319 ALLOWQUERY keycontent
321 g_zoneSpec.allowQuery = g_stringList;
327 OBRACE addressstatements EBRACE
333 addressstatements addressstatement SEMICOLON
339 DOTTED_DECIMAL_ADDRESS
346 OBRACE keystatements EBRACE
352 keystatements keystatement SEMICOLON
360 StringListElem * elem;
362 elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
366 LogMsg("ERROR: memory allocation failure");
372 elem->next = g_stringList;
379 DOTTED_DECIMAL_ADDRESS
387 OBRACE zonestatements EBRACE SEMICOLON
411 void yyerror( const char *str )
413 fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
431 DomainAuthInfo * key;
438 // Tear down the current zone specifiers
444 DNSZone * next = zone->next;
446 key = zone->updateKeys;
450 DomainAuthInfo * nextKey = key->next;
457 key = zone->queryKeys;
461 DomainAuthInfo * nextKey = key->next;
475 yyin = fopen( file, "r" );
476 require_action( yyin, exit, err = 0 );
478 err = yyparse( ( void* ) d );
479 require_action( !err, exit, err = 1 );
481 for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next )
483 StringListElem * elem;
486 zone = ( DNSZone* ) malloc( sizeof( DNSZone ) );
487 require_action( zone, exit, err = 1 );
488 memset( zone, 0, sizeof( DNSZone ) );
490 zone->next = d->zones;
493 // Fill in the domainname
495 ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name );
496 require_action( ok, exit, err = 1 );
500 zone->type = zoneSpec->type;
502 // Fill in the allow-update keys
504 for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next )
506 mDNSBool found = mDNSfalse;
508 for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
510 if ( strcmp( elem->string, keySpec->name ) == 0 )
512 DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) );
514 require_action( authInfo, exit, err = 1 );
515 memset( authInfo, 0, sizeof( DomainAuthInfo ) );
517 ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
518 if (!ok) { free(authInfo); err = 1; goto exit; }
520 keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
521 if (keylen < 0) { free(authInfo); err = 1; goto exit; }
523 authInfo->next = zone->updateKeys;
524 zone->updateKeys = authInfo;
533 require_action( found, exit, err = 1 );
536 // Fill in the allow-query keys
538 for ( elem = zoneSpec->allowQuery; elem; elem = elem->next )
540 mDNSBool found = mDNSfalse;
542 for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
544 if ( strcmp( elem->string, keySpec->name ) == 0 )
546 DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) );
548 require_action( authInfo, exit, err = 1 );
549 memset( authInfo, 0, sizeof( DomainAuthInfo ) );
551 ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
552 if (!ok) { free(authInfo); err = 1; goto exit; }
554 keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
555 if (keylen < 0) { free(authInfo); err = 1; goto exit; }
557 authInfo->next = zone->queryKeys;
558 zone->queryKeys = authInfo;
567 require_action( found, exit, err = 1 );
584 DaemonInfo * d = ( DaemonInfo* ) context;
586 if ( strlen( info->source_address ) )
588 inet_pton( AF_INET, info->source_address, &d->addr.sin_addr );
591 if ( info->source_port )
593 d->addr.sin_port = htons( ( mDNSu16 ) info->source_port );
596 if ( strlen( info->server_address ) )
598 inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr );
601 if ( info->server_port )
603 d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port );
606 if ( info->private_port )
608 d->private_port = mDNSOpaque16fromIntVal( info->private_port );
611 if ( info->llq_port )
613 d->llq_port = mDNSOpaque16fromIntVal( info->llq_port );