• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
yyerror(const char * str)381 void yyerror( const char *str )
382 {
383         fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
384 }
385 
yywrap()386 int yywrap()
387 {
388         return 1;
389 }
390 
391 
392 int
ParseConfig(DaemonInfo * d,const char * file)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
SetupOptions(OptionsInfo * info,void * context)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