Home | History | Annotate | Download | only in mDNSShared
      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 
     18 %{
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 #include "mDNSEmbeddedAPI.h"
     23 #include "DebugServices.h"
     24 #include "dnsextd.h"
     25 
     26 void yyerror( const char* error );
     27 int  yylex(void);
     28 
     29 
     30 typedef struct StringListElem
     31 {
     32 	char					*	string;
     33 	struct StringListElem	*	next;
     34 } StringListElem;
     35 
     36 
     37 typedef struct OptionsInfo
     38 {
     39 	char	server_address[ 256 ];
     40 	int		server_port;
     41 	char	source_address[ 256 ];
     42 	int		source_port;
     43 	int		private_port;
     44 	int		llq_port;
     45 } OptionsInfo;
     46 
     47 
     48 typedef struct ZoneInfo
     49 {
     50 	char	name[ 256 ];
     51 	char	certificate_name[ 256 ];
     52 	char	allow_clients_file[ 256 ];
     53 	char	allow_clients[ 256 ];
     54 	char	key[ 256 ];
     55 } ZoneInfo;
     56 
     57 
     58 typedef struct KeySpec
     59 {
     60 	char 				name[ 256 ];
     61 	char				algorithm[ 256 ];
     62 	char				secret[ 256 ];
     63 	struct KeySpec	*	next;
     64 } KeySpec;
     65 
     66 
     67 typedef struct ZoneSpec
     68 {
     69 	char				name[ 256 ];
     70 	DNSZoneSpecType		type;
     71 	StringListElem	*	allowUpdate;
     72 	StringListElem	*	allowQuery;
     73 	char				key[ 256 ];
     74 	struct ZoneSpec	*	next;
     75 } ZoneSpec;
     76 
     77 
     78 static StringListElem	*	g_stringList = NULL;
     79 static KeySpec			*	g_keys;
     80 static ZoneSpec			*	g_zones;
     81 static ZoneSpec				g_zoneSpec;
     82 static const char		*	g_filename;
     83 
     84 #define YYPARSE_PARAM  context
     85 
     86 void
     87 SetupOptions
     88 	(
     89 	OptionsInfo	*	info,
     90 	void		*	context
     91 	);
     92 
     93 %}
     94 
     95 %union
     96 {
     97 	int			number;
     98 	char	*	string;
     99 }
    100 
    101 %token	OPTIONS
    102 %token	LISTEN_ON
    103 %token	NAMESERVER
    104 %token	PORT
    105 %token	ADDRESS
    106 %token	LLQ
    107 %token	PUBLIC
    108 %token  PRIVATE
    109 %token  ALLOWUPDATE
    110 %token  ALLOWQUERY
    111 %token	KEY
    112 %token  ALGORITHM
    113 %token  SECRET
    114 %token  ISSUER
    115 %token  SERIAL
    116 %token	ZONE
    117 %token  TYPE
    118 %token	ALLOW
    119 %token	OBRACE
    120 %token	EBRACE
    121 %token	SEMICOLON
    122 %token 	IN
    123 %token	<string>	DOTTED_DECIMAL_ADDRESS
    124 %token	<string>	WILDCARD
    125 %token	<string>	DOMAINNAME
    126 %token	<string>	HOSTNAME
    127 %token	<string>	QUOTEDSTRING
    128 %token	<number> 	NUMBER
    129 
    130 %type	<string>	addressstatement
    131 %type	<string>	networkaddress
    132 
    133 %%
    134 
    135 commands:
    136         |
    137         commands command SEMICOLON
    138         ;
    139 
    140 
    141 command:
    142 		options_set
    143 		|
    144         zone_set
    145 		|
    146 		key_set
    147         ;
    148 
    149 
    150 options_set:
    151 		OPTIONS optionscontent
    152 		{
    153 			// SetupOptions( &g_optionsInfo, context );
    154 		}
    155 		;
    156 
    157 optionscontent:
    158 		OBRACE optionsstatements EBRACE
    159 		;
    160 
    161 optionsstatements:
    162 		|
    163 		optionsstatements optionsstatement SEMICOLON
    164 		;
    165 
    166 
    167 optionsstatement:
    168 		statements
    169 		|
    170 		LISTEN_ON addresscontent
    171 		{
    172 		}
    173 		|
    174 		LISTEN_ON PORT NUMBER addresscontent
    175 		{
    176 		}
    177 		|
    178 		NAMESERVER ADDRESS networkaddress
    179 		{
    180 		}
    181 		|
    182 		NAMESERVER ADDRESS networkaddress PORT NUMBER
    183 		{
    184 		}
    185 		|
    186 		PRIVATE PORT NUMBER
    187 		{
    188 			( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( $3 );
    189 		}
    190 		|
    191 		LLQ PORT NUMBER
    192 		{
    193 			( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( $3 );
    194 		}
    195 		;
    196 
    197 key_set:
    198         KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE
    199         {
    200 			KeySpec	* keySpec;
    201 
    202 			keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) );
    203 
    204 			if ( !keySpec )
    205 				{
    206 				LogMsg("ERROR: memory allocation failure");
    207 				YYABORT;
    208 				}
    209 
    210 			strncpy( keySpec->name, $2, sizeof( keySpec->name ) );
    211 			strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) );
    212 
    213 			keySpec->next	= g_keys;
    214 			g_keys			= keySpec;
    215         }
    216         ;
    217 
    218 zone_set:
    219 		ZONE QUOTEDSTRING zonecontent
    220 		{
    221 			ZoneSpec * zoneSpec;
    222 
    223 			zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
    224 
    225 			if ( !zoneSpec )
    226 				{
    227 				LogMsg("ERROR: memory allocation failure");
    228 				YYABORT;
    229 				}
    230 
    231 			strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
    232 			zoneSpec->type = g_zoneSpec.type;
    233 			strcpy( zoneSpec->key, g_zoneSpec.key );
    234 			zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
    235 			zoneSpec->allowQuery = g_zoneSpec.allowQuery;
    236 
    237 			zoneSpec->next = g_zones;
    238 			g_zones = zoneSpec;
    239 		}
    240 		|
    241 		ZONE QUOTEDSTRING IN zonecontent
    242         {
    243 			ZoneSpec * zoneSpec;
    244 
    245 			zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
    246 
    247 			if ( !zoneSpec )
    248 				{
    249 				LogMsg("ERROR: memory allocation failure");
    250 				YYABORT;
    251 				}
    252 
    253 			strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
    254 			zoneSpec->type = g_zoneSpec.type;
    255 			strcpy( zoneSpec->key, g_zoneSpec.key );
    256 			zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
    257 			zoneSpec->allowQuery = g_zoneSpec.allowQuery;
    258 
    259 			zoneSpec->next = g_zones;
    260 			g_zones = zoneSpec;
    261 		}
    262         ;
    263 
    264 zonecontent:
    265 		OBRACE zonestatements EBRACE
    266 
    267 zonestatements:
    268         |
    269         zonestatements zonestatement SEMICOLON
    270         ;
    271 
    272 zonestatement:
    273 		TYPE PUBLIC
    274 		{
    275 			g_zoneSpec.type = kDNSZonePublic;
    276 		}
    277 		|
    278 		TYPE PRIVATE
    279 		{
    280 			g_zoneSpec.type = kDNSZonePrivate;
    281 		}
    282 		|
    283 		ALLOWUPDATE keycontent
    284 		{
    285 			g_zoneSpec.allowUpdate = g_stringList;
    286 			g_stringList = NULL;
    287 		}
    288 		|
    289 		ALLOWQUERY keycontent
    290 		{
    291 			g_zoneSpec.allowQuery = g_stringList;
    292 			g_stringList = NULL;
    293 		}
    294         ;
    295 
    296 addresscontent:
    297 		OBRACE addressstatements EBRACE
    298 		{
    299 		}
    300 
    301 addressstatements:
    302 		|
    303 		addressstatements addressstatement SEMICOLON
    304 		{
    305 		}
    306 		;
    307 
    308 addressstatement:
    309 		DOTTED_DECIMAL_ADDRESS
    310 		{
    311 		}
    312 		;
    313 
    314 
    315 keycontent:
    316 		OBRACE keystatements EBRACE
    317 		{
    318 		}
    319 
    320 keystatements:
    321 		|
    322 		keystatements keystatement SEMICOLON
    323 		{
    324 		}
    325 		;
    326 
    327 keystatement:
    328 		KEY DOMAINNAME
    329 		{
    330 			StringListElem * elem;
    331 
    332 			elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
    333 
    334 			if ( !elem )
    335 				{
    336 				LogMsg("ERROR: memory allocation failure");
    337 				YYABORT;
    338 				}
    339 
    340 			elem->string = $2;
    341 
    342 			elem->next		= g_stringList;
    343 			g_stringList	= elem;
    344 		}
    345 		;
    346 
    347 
    348 networkaddress:
    349 		DOTTED_DECIMAL_ADDRESS
    350 		|
    351 		HOSTNAME
    352 		|
    353 		WILDCARD
    354 		;
    355 
    356 block:
    357 		OBRACE zonestatements EBRACE SEMICOLON
    358         ;
    359 
    360 statements:
    361         |
    362 		statements statement
    363         ;
    364 
    365 statement:
    366 		block
    367 		{
    368 			$<string>$ = NULL;
    369 		}
    370 		|
    371 		QUOTEDSTRING
    372 		{
    373 			$<string>$ = $1;
    374 		}
    375 %%
    376 
    377 int yywrap(void);
    378 
    379 extern int yylineno;
    380 
    381 void yyerror( const char *str )
    382 {
    383         fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
    384 }
    385 
    386 int yywrap()
    387 {
    388         return 1;
    389 }
    390 
    391 
    392 int
    393 ParseConfig
    394 	(
    395 	DaemonInfo	*	d,
    396 	const char	*	file
    397 	)
    398 	{
    399 	extern FILE		*	yyin;
    400 	DNSZone			*	zone;
    401 	DomainAuthInfo	*	key;
    402 	KeySpec			*	keySpec;
    403 	ZoneSpec		*	zoneSpec;
    404 	int					err = 0;
    405 
    406 	g_filename = file;
    407 
    408 	// Tear down the current zone specifiers
    409 
    410 	zone = d->zones;
    411 
    412 	while ( zone )
    413 		{
    414 		DNSZone * next = zone->next;
    415 
    416 		key = zone->updateKeys;
    417 
    418 		while ( key )
    419 			{
    420 			DomainAuthInfo * nextKey = key->next;
    421 
    422 			free( key );
    423 
    424 			key = nextKey;
    425 			}
    426 
    427 		key = zone->queryKeys;
    428 
    429 		while ( key )
    430 			{
    431 			DomainAuthInfo * nextKey = key->next;
    432 
    433 			free( key );
    434 
    435 			key = nextKey;
    436 			}
    437 
    438 		free( zone );
    439 
    440 		zone = next;
    441 		}
    442 
    443 	d->zones = NULL;
    444 
    445 	yyin = fopen( file, "r" );
    446 	require_action( yyin, exit, err = 0 );
    447 
    448 	err = yyparse( ( void* ) d );
    449 	require_action( !err, exit, err = 1 );
    450 
    451 	for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next )
    452 		{
    453 		StringListElem  *   elem;
    454 		mDNSu8			*	ok;
    455 
    456 		zone = ( DNSZone* ) malloc( sizeof( DNSZone ) );
    457 		require_action( zone, exit, err = 1 );
    458 		memset( zone, 0, sizeof( DNSZone ) );
    459 
    460 		zone->next	= d->zones;
    461 		d->zones	= zone;
    462 
    463 		// Fill in the domainname
    464 
    465 		ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name );
    466 		require_action( ok, exit, err = 1 );
    467 
    468 		// Fill in the type
    469 
    470 		zone->type = zoneSpec->type;
    471 
    472 		// Fill in the allow-update keys
    473 
    474 		for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next )
    475 			{
    476 			mDNSBool found = mDNSfalse;
    477 
    478 			for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
    479 				{
    480 				if ( strcmp( elem->string, keySpec->name ) == 0 )
    481 					{
    482 					DomainAuthInfo	*	authInfo = malloc( sizeof( DomainAuthInfo ) );
    483 					mDNSs32				keylen;
    484 					require_action( authInfo, exit, err = 1 );
    485 					memset( authInfo, 0, sizeof( DomainAuthInfo ) );
    486 
    487 					ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
    488 					if (!ok) { free(authInfo); err = 1; goto exit; }
    489 
    490 					keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
    491 					if (keylen < 0) { free(authInfo); err = 1; goto exit; }
    492 
    493 					authInfo->next = zone->updateKeys;
    494 					zone->updateKeys = authInfo;
    495 
    496 					found = mDNStrue;
    497 
    498 					break;
    499 					}
    500 				}
    501 
    502 			// Log this
    503 			require_action( found, exit, err = 1 );
    504 			}
    505 
    506 		// Fill in the allow-query keys
    507 
    508 		for ( elem = zoneSpec->allowQuery; elem; elem = elem->next )
    509 			{
    510 			mDNSBool found = mDNSfalse;
    511 
    512 			for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
    513 				{
    514 				if ( strcmp( elem->string, keySpec->name ) == 0 )
    515 					{
    516 					DomainAuthInfo	*	authInfo = malloc( sizeof( DomainAuthInfo ) );
    517 					mDNSs32				keylen;
    518 					require_action( authInfo, exit, err = 1 );
    519 					memset( authInfo, 0, sizeof( DomainAuthInfo ) );
    520 
    521 					ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
    522 					if (!ok) { free(authInfo); err = 1; goto exit; }
    523 
    524 					keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
    525 					if (keylen < 0) { free(authInfo); err = 1; goto exit; }
    526 
    527 					authInfo->next = zone->queryKeys;
    528 					zone->queryKeys = authInfo;
    529 
    530 					found = mDNStrue;
    531 
    532 					break;
    533 					}
    534 				}
    535 
    536 			// Log this
    537 			require_action( found, exit, err = 1 );
    538 			}
    539 		}
    540 
    541 exit:
    542 
    543 	return err;
    544 	}
    545 
    546 
    547 void
    548 SetupOptions
    549 	(
    550 	OptionsInfo	*	info,
    551 	void		*	context
    552 	)
    553 	{
    554 	DaemonInfo * d = ( DaemonInfo* ) context;
    555 
    556 	if ( strlen( info->source_address ) )
    557 		{
    558 		inet_pton( AF_INET, info->source_address, &d->addr.sin_addr );
    559 		}
    560 
    561 	if ( info->source_port )
    562 		{
    563 		d->addr.sin_port = htons( ( mDNSu16 ) info->source_port );
    564 		}
    565 
    566 	if ( strlen( info->server_address ) )
    567 		{
    568 		inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr );
    569 		}
    570 
    571 	if ( info->server_port )
    572 		{
    573 		d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port );
    574 		}
    575 
    576 	if ( info->private_port )
    577 		{
    578 		d->private_port = mDNSOpaque16fromIntVal( info->private_port );
    579 		}
    580 
    581 	if ( info->llq_port )
    582 		{
    583 		d->llq_port = mDNSOpaque16fromIntVal( info->llq_port );
    584 		}
    585 	}
    586