178d5fdc3Schristos /* -*- Mode: C; tab-width: 4 -*-
278d5fdc3Schristos  *
3*c7c857efSchristos  * Copyright (c) 2006-2010 Apple Inc. All rights reserved.
478d5fdc3Schristos  *
578d5fdc3Schristos  * Licensed under the Apache License, Version 2.0 (the "License");
678d5fdc3Schristos  * you may not use this file except in compliance with the License.
778d5fdc3Schristos  * You may obtain a copy of the License at
878d5fdc3Schristos  *
978d5fdc3Schristos  *     http://www.apache.org/licenses/LICENSE-2.0
1078d5fdc3Schristos  *
1178d5fdc3Schristos  * Unless required by applicable law or agreed to in writing, software
1278d5fdc3Schristos  * distributed under the License is distributed on an "AS IS" BASIS,
1378d5fdc3Schristos  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1478d5fdc3Schristos  * See the License for the specific language governing permissions and
1578d5fdc3Schristos  * limitations under the License.
1678d5fdc3Schristos  */
1778d5fdc3Schristos 
1878d5fdc3Schristos %{
1978d5fdc3Schristos #include <stdio.h>
2078d5fdc3Schristos #include <stdlib.h>
2178d5fdc3Schristos #include <string.h>
2278d5fdc3Schristos #include "mDNSEmbeddedAPI.h"
2378d5fdc3Schristos #include "DebugServices.h"
2478d5fdc3Schristos #include "dnsextd.h"
2578d5fdc3Schristos 
2678d5fdc3Schristos void yyerror( const char* error );
2778d5fdc3Schristos int  yylex(void);
2878d5fdc3Schristos 
2978d5fdc3Schristos 
3078d5fdc3Schristos typedef struct StringListElem
3178d5fdc3Schristos {
3278d5fdc3Schristos 	char					*	string;
3378d5fdc3Schristos 	struct StringListElem	*	next;
3478d5fdc3Schristos } StringListElem;
3578d5fdc3Schristos 
3678d5fdc3Schristos 
3778d5fdc3Schristos typedef struct OptionsInfo
3878d5fdc3Schristos {
3978d5fdc3Schristos 	char	server_address[ 256 ];
4078d5fdc3Schristos 	int		server_port;
4178d5fdc3Schristos 	char	source_address[ 256 ];
4278d5fdc3Schristos 	int		source_port;
4378d5fdc3Schristos 	int		private_port;
4478d5fdc3Schristos 	int		llq_port;
4578d5fdc3Schristos } OptionsInfo;
4678d5fdc3Schristos 
4778d5fdc3Schristos 
4878d5fdc3Schristos typedef struct ZoneInfo
4978d5fdc3Schristos {
5078d5fdc3Schristos 	char	name[ 256 ];
5178d5fdc3Schristos 	char	certificate_name[ 256 ];
5278d5fdc3Schristos 	char	allow_clients_file[ 256 ];
5378d5fdc3Schristos 	char	allow_clients[ 256 ];
5478d5fdc3Schristos 	char	key[ 256 ];
5578d5fdc3Schristos } ZoneInfo;
5678d5fdc3Schristos 
5778d5fdc3Schristos 
5878d5fdc3Schristos typedef struct KeySpec
5978d5fdc3Schristos {
6078d5fdc3Schristos 	char 				name[ 256 ];
6178d5fdc3Schristos 	char				algorithm[ 256 ];
6278d5fdc3Schristos 	char				secret[ 256 ];
6378d5fdc3Schristos 	struct KeySpec	*	next;
6478d5fdc3Schristos } KeySpec;
6578d5fdc3Schristos 
6678d5fdc3Schristos 
6778d5fdc3Schristos typedef struct ZoneSpec
6878d5fdc3Schristos {
6978d5fdc3Schristos 	char				name[ 256 ];
7078d5fdc3Schristos 	DNSZoneSpecType		type;
7178d5fdc3Schristos 	StringListElem	*	allowUpdate;
7278d5fdc3Schristos 	StringListElem	*	allowQuery;
7378d5fdc3Schristos 	char				key[ 256 ];
7478d5fdc3Schristos 	struct ZoneSpec	*	next;
7578d5fdc3Schristos } ZoneSpec;
7678d5fdc3Schristos 
7778d5fdc3Schristos 
7878d5fdc3Schristos static StringListElem	*	g_stringList = NULL;
79*c7c857efSchristos static StringListElem	*	g_addrList = NULL;
8078d5fdc3Schristos static KeySpec			*	g_keys;
8178d5fdc3Schristos static ZoneSpec			*	g_zones;
8278d5fdc3Schristos static ZoneSpec				g_zoneSpec;
8378d5fdc3Schristos static const char		*	g_filename;
8478d5fdc3Schristos 
8578d5fdc3Schristos #define YYPARSE_PARAM  context
8678d5fdc3Schristos 
8778d5fdc3Schristos void
8878d5fdc3Schristos SetupOptions
8978d5fdc3Schristos 	(
9078d5fdc3Schristos 	OptionsInfo	*	info,
9178d5fdc3Schristos 	void		*	context
9278d5fdc3Schristos 	);
9378d5fdc3Schristos 
9478d5fdc3Schristos %}
9578d5fdc3Schristos 
9678d5fdc3Schristos %union
9778d5fdc3Schristos {
9878d5fdc3Schristos 	int			number;
9978d5fdc3Schristos 	char	*	string;
10078d5fdc3Schristos }
10178d5fdc3Schristos 
10278d5fdc3Schristos %token	OPTIONS
10378d5fdc3Schristos %token	LISTEN_ON
10478d5fdc3Schristos %token	NAMESERVER
10578d5fdc3Schristos %token	PORT
10678d5fdc3Schristos %token	ADDRESS
10778d5fdc3Schristos %token	LLQ
10878d5fdc3Schristos %token	PUBLIC
10978d5fdc3Schristos %token  PRIVATE
11078d5fdc3Schristos %token  ALLOWUPDATE
11178d5fdc3Schristos %token  ALLOWQUERY
11278d5fdc3Schristos %token	KEY
11378d5fdc3Schristos %token  ALGORITHM
11478d5fdc3Schristos %token  SECRET
11578d5fdc3Schristos %token  ISSUER
11678d5fdc3Schristos %token  SERIAL
11778d5fdc3Schristos %token	ZONE
11878d5fdc3Schristos %token  TYPE
11978d5fdc3Schristos %token	ALLOW
12078d5fdc3Schristos %token	OBRACE
12178d5fdc3Schristos %token	EBRACE
12278d5fdc3Schristos %token	SEMICOLON
12378d5fdc3Schristos %token 	IN
12478d5fdc3Schristos %token	<string>	DOTTED_DECIMAL_ADDRESS
12578d5fdc3Schristos %token	<string>	WILDCARD
12678d5fdc3Schristos %token	<string>	DOMAINNAME
12778d5fdc3Schristos %token	<string>	HOSTNAME
12878d5fdc3Schristos %token	<string>	QUOTEDSTRING
12978d5fdc3Schristos %token	<number> 	NUMBER
13078d5fdc3Schristos 
13178d5fdc3Schristos %type	<string>	addressstatement
13278d5fdc3Schristos %type	<string>	networkaddress
13378d5fdc3Schristos 
13478d5fdc3Schristos %%
13578d5fdc3Schristos 
13678d5fdc3Schristos commands:
13778d5fdc3Schristos         |
13878d5fdc3Schristos         commands command SEMICOLON
13978d5fdc3Schristos         ;
14078d5fdc3Schristos 
14178d5fdc3Schristos 
14278d5fdc3Schristos command:
14378d5fdc3Schristos 		options_set
14478d5fdc3Schristos 		|
14578d5fdc3Schristos         zone_set
14678d5fdc3Schristos 		|
14778d5fdc3Schristos 		key_set
14878d5fdc3Schristos         ;
14978d5fdc3Schristos 
15078d5fdc3Schristos 
15178d5fdc3Schristos options_set:
15278d5fdc3Schristos 		OPTIONS optionscontent
15378d5fdc3Schristos 		{
15478d5fdc3Schristos 			// SetupOptions( &g_optionsInfo, context );
15578d5fdc3Schristos 		}
15678d5fdc3Schristos 		;
15778d5fdc3Schristos 
15878d5fdc3Schristos optionscontent:
15978d5fdc3Schristos 		OBRACE optionsstatements EBRACE
16078d5fdc3Schristos 		;
16178d5fdc3Schristos 
16278d5fdc3Schristos optionsstatements:
16378d5fdc3Schristos 		|
16478d5fdc3Schristos 		optionsstatements optionsstatement SEMICOLON
16578d5fdc3Schristos 		;
16678d5fdc3Schristos 
16778d5fdc3Schristos 
16878d5fdc3Schristos optionsstatement:
16978d5fdc3Schristos 		statements
17078d5fdc3Schristos 		|
17178d5fdc3Schristos 		LISTEN_ON addresscontent
17278d5fdc3Schristos 		{
17378d5fdc3Schristos 		}
17478d5fdc3Schristos 		|
17578d5fdc3Schristos 		LISTEN_ON PORT NUMBER addresscontent
17678d5fdc3Schristos 		{
177*c7c857efSchristos 			mDNSIPPort listen_port = mDNSOpaque16fromIntVal( $3 );
178*c7c857efSchristos 			DaemonInfo* d = ( DaemonInfo* ) context;
179*c7c857efSchristos 			d->addr.sin_port = ( listen_port.NotAnInteger) ? listen_port.NotAnInteger : UnicastDNSPort.NotAnInteger;
180*c7c857efSchristos 			StringListElem* addr = g_addrList;
181*c7c857efSchristos 			while (addr != NULL)
182*c7c857efSchristos 			{
183*c7c857efSchristos 				StringListElem* next;
184*c7c857efSchristos 				// The first ipv4 address in {,} is used; the rest are ignored.
185*c7c857efSchristos 				if (inet_pton( AF_INET, addr->string, &d->addr.sin_addr ) == 0) {
186*c7c857efSchristos 					inet_pton( AF_INET, "127.0.0.1", &d->ns_addr.sin_addr );
187*c7c857efSchristos 					LogMsg("LISTEN_ON: An invalid ipv4 address, %s, detected.", addr->string);
188*c7c857efSchristos 				}
189*c7c857efSchristos 				next = addr->next;
190*c7c857efSchristos 				free(addr);
191*c7c857efSchristos 				addr = next;
192*c7c857efSchristos 			}
19378d5fdc3Schristos 		}
19478d5fdc3Schristos 		|
19578d5fdc3Schristos 		NAMESERVER ADDRESS networkaddress
19678d5fdc3Schristos 		{
19778d5fdc3Schristos 		}
19878d5fdc3Schristos 		|
19978d5fdc3Schristos 		NAMESERVER ADDRESS networkaddress PORT NUMBER
20078d5fdc3Schristos 		{
20178d5fdc3Schristos 		}
20278d5fdc3Schristos 		|
20378d5fdc3Schristos 		PRIVATE PORT NUMBER
20478d5fdc3Schristos 		{
20578d5fdc3Schristos 			( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( $3 );
20678d5fdc3Schristos 		}
20778d5fdc3Schristos 		|
20878d5fdc3Schristos 		LLQ PORT NUMBER
20978d5fdc3Schristos 		{
21078d5fdc3Schristos 			( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( $3 );
21178d5fdc3Schristos 		}
21278d5fdc3Schristos 		;
21378d5fdc3Schristos 
21478d5fdc3Schristos key_set:
21578d5fdc3Schristos         KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE
21678d5fdc3Schristos         {
21778d5fdc3Schristos 			KeySpec	* keySpec;
21878d5fdc3Schristos 
21978d5fdc3Schristos 			keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) );
22078d5fdc3Schristos 
22178d5fdc3Schristos 			if ( !keySpec )
22278d5fdc3Schristos 				{
22378d5fdc3Schristos 				LogMsg("ERROR: memory allocation failure");
22478d5fdc3Schristos 				YYABORT;
22578d5fdc3Schristos 				}
22678d5fdc3Schristos 
22778d5fdc3Schristos 			strncpy( keySpec->name, $2, sizeof( keySpec->name ) );
22878d5fdc3Schristos 			strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) );
22978d5fdc3Schristos 
23078d5fdc3Schristos 			keySpec->next	= g_keys;
23178d5fdc3Schristos 			g_keys			= keySpec;
23278d5fdc3Schristos         }
23378d5fdc3Schristos         ;
23478d5fdc3Schristos 
23578d5fdc3Schristos zone_set:
23678d5fdc3Schristos 		ZONE QUOTEDSTRING zonecontent
23778d5fdc3Schristos 		{
23878d5fdc3Schristos 			ZoneSpec * zoneSpec;
23978d5fdc3Schristos 
24078d5fdc3Schristos 			zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
24178d5fdc3Schristos 
24278d5fdc3Schristos 			if ( !zoneSpec )
24378d5fdc3Schristos 				{
24478d5fdc3Schristos 				LogMsg("ERROR: memory allocation failure");
24578d5fdc3Schristos 				YYABORT;
24678d5fdc3Schristos 				}
24778d5fdc3Schristos 
24878d5fdc3Schristos 			strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
24978d5fdc3Schristos 			zoneSpec->type = g_zoneSpec.type;
25078d5fdc3Schristos 			strcpy( zoneSpec->key, g_zoneSpec.key );
25178d5fdc3Schristos 			zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
25278d5fdc3Schristos 			zoneSpec->allowQuery = g_zoneSpec.allowQuery;
25378d5fdc3Schristos 
25478d5fdc3Schristos 			zoneSpec->next = g_zones;
25578d5fdc3Schristos 			g_zones = zoneSpec;
25678d5fdc3Schristos 		}
25778d5fdc3Schristos 		|
25878d5fdc3Schristos 		ZONE QUOTEDSTRING IN zonecontent
25978d5fdc3Schristos         {
26078d5fdc3Schristos 			ZoneSpec * zoneSpec;
26178d5fdc3Schristos 
26278d5fdc3Schristos 			zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) );
26378d5fdc3Schristos 
26478d5fdc3Schristos 			if ( !zoneSpec )
26578d5fdc3Schristos 				{
26678d5fdc3Schristos 				LogMsg("ERROR: memory allocation failure");
26778d5fdc3Schristos 				YYABORT;
26878d5fdc3Schristos 				}
26978d5fdc3Schristos 
27078d5fdc3Schristos 			strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) );
27178d5fdc3Schristos 			zoneSpec->type = g_zoneSpec.type;
27278d5fdc3Schristos 			strcpy( zoneSpec->key, g_zoneSpec.key );
27378d5fdc3Schristos 			zoneSpec->allowUpdate = g_zoneSpec.allowUpdate;
27478d5fdc3Schristos 			zoneSpec->allowQuery = g_zoneSpec.allowQuery;
27578d5fdc3Schristos 
27678d5fdc3Schristos 			zoneSpec->next = g_zones;
27778d5fdc3Schristos 			g_zones = zoneSpec;
27878d5fdc3Schristos 		}
27978d5fdc3Schristos         ;
28078d5fdc3Schristos 
28178d5fdc3Schristos zonecontent:
28278d5fdc3Schristos 		OBRACE zonestatements EBRACE
28378d5fdc3Schristos 
28478d5fdc3Schristos zonestatements:
28578d5fdc3Schristos         |
28678d5fdc3Schristos         zonestatements zonestatement SEMICOLON
28778d5fdc3Schristos         ;
28878d5fdc3Schristos 
28978d5fdc3Schristos zonestatement:
29078d5fdc3Schristos 		TYPE PUBLIC
29178d5fdc3Schristos 		{
29278d5fdc3Schristos 			g_zoneSpec.type = kDNSZonePublic;
29378d5fdc3Schristos 		}
29478d5fdc3Schristos 		|
29578d5fdc3Schristos 		TYPE PRIVATE
29678d5fdc3Schristos 		{
29778d5fdc3Schristos 			g_zoneSpec.type = kDNSZonePrivate;
29878d5fdc3Schristos 		}
29978d5fdc3Schristos 		|
30078d5fdc3Schristos 		ALLOWUPDATE keycontent
30178d5fdc3Schristos 		{
30278d5fdc3Schristos 			g_zoneSpec.allowUpdate = g_stringList;
30378d5fdc3Schristos 			g_stringList = NULL;
30478d5fdc3Schristos 		}
30578d5fdc3Schristos 		|
30678d5fdc3Schristos 		ALLOWQUERY keycontent
30778d5fdc3Schristos 		{
30878d5fdc3Schristos 			g_zoneSpec.allowQuery = g_stringList;
30978d5fdc3Schristos 			g_stringList = NULL;
31078d5fdc3Schristos 		}
31178d5fdc3Schristos         ;
31278d5fdc3Schristos 
31378d5fdc3Schristos addresscontent:
31478d5fdc3Schristos 		OBRACE addressstatements EBRACE
31578d5fdc3Schristos 		{
31678d5fdc3Schristos 		}
31778d5fdc3Schristos 
31878d5fdc3Schristos addressstatements:
31978d5fdc3Schristos 		|
32078d5fdc3Schristos 		addressstatements addressstatement SEMICOLON
32178d5fdc3Schristos 		{
32278d5fdc3Schristos 		}
32378d5fdc3Schristos 		;
32478d5fdc3Schristos 
32578d5fdc3Schristos addressstatement:
32678d5fdc3Schristos 		DOTTED_DECIMAL_ADDRESS
32778d5fdc3Schristos 		{
328*c7c857efSchristos 			StringListElem * elem;
329*c7c857efSchristos 
330*c7c857efSchristos 			elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
331*c7c857efSchristos 
332*c7c857efSchristos 			if ( !elem )
333*c7c857efSchristos 			{
334*c7c857efSchristos 				LogMsg("ERROR: memory allocation failure");
335*c7c857efSchristos 				YYABORT;
336*c7c857efSchristos 			}
337*c7c857efSchristos 
338*c7c857efSchristos 			elem->string = $1;
339*c7c857efSchristos 
340*c7c857efSchristos 			elem->next		= g_addrList;
341*c7c857efSchristos 			g_addrList		= elem;
34278d5fdc3Schristos 		}
34378d5fdc3Schristos 		;
34478d5fdc3Schristos 
34578d5fdc3Schristos 
34678d5fdc3Schristos keycontent:
34778d5fdc3Schristos 		OBRACE keystatements EBRACE
34878d5fdc3Schristos 		{
34978d5fdc3Schristos 		}
35078d5fdc3Schristos 
35178d5fdc3Schristos keystatements:
35278d5fdc3Schristos 		|
35378d5fdc3Schristos 		keystatements keystatement SEMICOLON
35478d5fdc3Schristos 		{
35578d5fdc3Schristos 		}
35678d5fdc3Schristos 		;
35778d5fdc3Schristos 
35878d5fdc3Schristos keystatement:
35978d5fdc3Schristos 		KEY DOMAINNAME
36078d5fdc3Schristos 		{
36178d5fdc3Schristos 			StringListElem * elem;
36278d5fdc3Schristos 
36378d5fdc3Schristos 			elem = ( StringListElem* ) malloc( sizeof( StringListElem ) );
36478d5fdc3Schristos 
36578d5fdc3Schristos 			if ( !elem )
36678d5fdc3Schristos 				{
36778d5fdc3Schristos 				LogMsg("ERROR: memory allocation failure");
36878d5fdc3Schristos 				YYABORT;
36978d5fdc3Schristos 				}
37078d5fdc3Schristos 
37178d5fdc3Schristos 			elem->string = $2;
37278d5fdc3Schristos 
37378d5fdc3Schristos 			elem->next		= g_stringList;
37478d5fdc3Schristos 			g_stringList	= elem;
37578d5fdc3Schristos 		}
37678d5fdc3Schristos 		;
37778d5fdc3Schristos 
37878d5fdc3Schristos 
37978d5fdc3Schristos networkaddress:
38078d5fdc3Schristos 		DOTTED_DECIMAL_ADDRESS
38178d5fdc3Schristos 		|
38278d5fdc3Schristos 		HOSTNAME
38378d5fdc3Schristos 		|
38478d5fdc3Schristos 		WILDCARD
38578d5fdc3Schristos 		;
38678d5fdc3Schristos 
38778d5fdc3Schristos block:
38878d5fdc3Schristos 		OBRACE zonestatements EBRACE SEMICOLON
38978d5fdc3Schristos         ;
39078d5fdc3Schristos 
39178d5fdc3Schristos statements:
39278d5fdc3Schristos         |
39378d5fdc3Schristos 		statements statement
39478d5fdc3Schristos         ;
39578d5fdc3Schristos 
39678d5fdc3Schristos statement:
39778d5fdc3Schristos 		block
39878d5fdc3Schristos 		{
39978d5fdc3Schristos 			$<string>$ = NULL;
40078d5fdc3Schristos 		}
40178d5fdc3Schristos 		|
40278d5fdc3Schristos 		QUOTEDSTRING
40378d5fdc3Schristos 		{
40478d5fdc3Schristos 			$<string>$ = $1;
40578d5fdc3Schristos 		}
40678d5fdc3Schristos %%
40778d5fdc3Schristos 
40878d5fdc3Schristos int yywrap(void);
40978d5fdc3Schristos 
41078d5fdc3Schristos extern int yylineno;
41178d5fdc3Schristos 
yyerror(const char * str)41278d5fdc3Schristos void yyerror( const char *str )
41378d5fdc3Schristos {
41478d5fdc3Schristos         fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
41578d5fdc3Schristos }
41678d5fdc3Schristos 
yywrap()41778d5fdc3Schristos int yywrap()
41878d5fdc3Schristos {
41978d5fdc3Schristos         return 1;
42078d5fdc3Schristos }
42178d5fdc3Schristos 
42278d5fdc3Schristos 
42378d5fdc3Schristos int
ParseConfig(DaemonInfo * d,const char * file)42478d5fdc3Schristos ParseConfig
42578d5fdc3Schristos 	(
42678d5fdc3Schristos 	DaemonInfo	*	d,
42778d5fdc3Schristos 	const char	*	file
42878d5fdc3Schristos 	)
42978d5fdc3Schristos 	{
43078d5fdc3Schristos 	extern FILE		*	yyin;
43178d5fdc3Schristos 	DNSZone			*	zone;
43278d5fdc3Schristos 	DomainAuthInfo	*	key;
43378d5fdc3Schristos 	KeySpec			*	keySpec;
43478d5fdc3Schristos 	ZoneSpec		*	zoneSpec;
43578d5fdc3Schristos 	int					err = 0;
43678d5fdc3Schristos 
43778d5fdc3Schristos 	g_filename = file;
43878d5fdc3Schristos 
43978d5fdc3Schristos 	// Tear down the current zone specifiers
44078d5fdc3Schristos 
44178d5fdc3Schristos 	zone = d->zones;
44278d5fdc3Schristos 
44378d5fdc3Schristos 	while ( zone )
44478d5fdc3Schristos 		{
44578d5fdc3Schristos 		DNSZone * next = zone->next;
44678d5fdc3Schristos 
44778d5fdc3Schristos 		key = zone->updateKeys;
44878d5fdc3Schristos 
44978d5fdc3Schristos 		while ( key )
45078d5fdc3Schristos 			{
45178d5fdc3Schristos 			DomainAuthInfo * nextKey = key->next;
45278d5fdc3Schristos 
45378d5fdc3Schristos 			free( key );
45478d5fdc3Schristos 
45578d5fdc3Schristos 			key = nextKey;
45678d5fdc3Schristos 			}
45778d5fdc3Schristos 
45878d5fdc3Schristos 		key = zone->queryKeys;
45978d5fdc3Schristos 
46078d5fdc3Schristos 		while ( key )
46178d5fdc3Schristos 			{
46278d5fdc3Schristos 			DomainAuthInfo * nextKey = key->next;
46378d5fdc3Schristos 
46478d5fdc3Schristos 			free( key );
46578d5fdc3Schristos 
46678d5fdc3Schristos 			key = nextKey;
46778d5fdc3Schristos 			}
46878d5fdc3Schristos 
46978d5fdc3Schristos 		free( zone );
47078d5fdc3Schristos 
47178d5fdc3Schristos 		zone = next;
47278d5fdc3Schristos 		}
47378d5fdc3Schristos 
47478d5fdc3Schristos 	d->zones = NULL;
47578d5fdc3Schristos 
47678d5fdc3Schristos 	yyin = fopen( file, "r" );
47778d5fdc3Schristos 	require_action( yyin, exit, err = 0 );
47878d5fdc3Schristos 
47978d5fdc3Schristos 	err = yyparse( ( void* ) d );
48078d5fdc3Schristos 	require_action( !err, exit, err = 1 );
48178d5fdc3Schristos 
48278d5fdc3Schristos 	for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next )
48378d5fdc3Schristos 		{
48478d5fdc3Schristos 		StringListElem  *   elem;
48578d5fdc3Schristos 		mDNSu8			*	ok;
48678d5fdc3Schristos 
48778d5fdc3Schristos 		zone = ( DNSZone* ) malloc( sizeof( DNSZone ) );
48878d5fdc3Schristos 		require_action( zone, exit, err = 1 );
48978d5fdc3Schristos 		memset( zone, 0, sizeof( DNSZone ) );
49078d5fdc3Schristos 
49178d5fdc3Schristos 		zone->next	= d->zones;
49278d5fdc3Schristos 		d->zones	= zone;
49378d5fdc3Schristos 
49478d5fdc3Schristos 		// Fill in the domainname
49578d5fdc3Schristos 
49678d5fdc3Schristos 		ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name );
49778d5fdc3Schristos 		require_action( ok, exit, err = 1 );
49878d5fdc3Schristos 
49978d5fdc3Schristos 		// Fill in the type
50078d5fdc3Schristos 
50178d5fdc3Schristos 		zone->type = zoneSpec->type;
50278d5fdc3Schristos 
50378d5fdc3Schristos 		// Fill in the allow-update keys
50478d5fdc3Schristos 
50578d5fdc3Schristos 		for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next )
50678d5fdc3Schristos 			{
50778d5fdc3Schristos 			mDNSBool found = mDNSfalse;
50878d5fdc3Schristos 
50978d5fdc3Schristos 			for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
51078d5fdc3Schristos 				{
51178d5fdc3Schristos 				if ( strcmp( elem->string, keySpec->name ) == 0 )
51278d5fdc3Schristos 					{
51378d5fdc3Schristos 					DomainAuthInfo	*	authInfo = malloc( sizeof( DomainAuthInfo ) );
51478d5fdc3Schristos 					mDNSs32				keylen;
51578d5fdc3Schristos 					require_action( authInfo, exit, err = 1 );
51678d5fdc3Schristos 					memset( authInfo, 0, sizeof( DomainAuthInfo ) );
51778d5fdc3Schristos 
51878d5fdc3Schristos 					ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
51978d5fdc3Schristos 					if (!ok) { free(authInfo); err = 1; goto exit; }
52078d5fdc3Schristos 
52178d5fdc3Schristos 					keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
52278d5fdc3Schristos 					if (keylen < 0) { free(authInfo); err = 1; goto exit; }
52378d5fdc3Schristos 
52478d5fdc3Schristos 					authInfo->next = zone->updateKeys;
52578d5fdc3Schristos 					zone->updateKeys = authInfo;
52678d5fdc3Schristos 
52778d5fdc3Schristos 					found = mDNStrue;
52878d5fdc3Schristos 
52978d5fdc3Schristos 					break;
53078d5fdc3Schristos 					}
53178d5fdc3Schristos 				}
53278d5fdc3Schristos 
53378d5fdc3Schristos 			// Log this
53478d5fdc3Schristos 			require_action( found, exit, err = 1 );
53578d5fdc3Schristos 			}
53678d5fdc3Schristos 
53778d5fdc3Schristos 		// Fill in the allow-query keys
53878d5fdc3Schristos 
53978d5fdc3Schristos 		for ( elem = zoneSpec->allowQuery; elem; elem = elem->next )
54078d5fdc3Schristos 			{
54178d5fdc3Schristos 			mDNSBool found = mDNSfalse;
54278d5fdc3Schristos 
54378d5fdc3Schristos 			for ( keySpec = g_keys; keySpec; keySpec = keySpec->next )
54478d5fdc3Schristos 				{
54578d5fdc3Schristos 				if ( strcmp( elem->string, keySpec->name ) == 0 )
54678d5fdc3Schristos 					{
54778d5fdc3Schristos 					DomainAuthInfo	*	authInfo = malloc( sizeof( DomainAuthInfo ) );
54878d5fdc3Schristos 					mDNSs32				keylen;
54978d5fdc3Schristos 					require_action( authInfo, exit, err = 1 );
55078d5fdc3Schristos 					memset( authInfo, 0, sizeof( DomainAuthInfo ) );
55178d5fdc3Schristos 
55278d5fdc3Schristos 					ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name );
55378d5fdc3Schristos 					if (!ok) { free(authInfo); err = 1; goto exit; }
55478d5fdc3Schristos 
55578d5fdc3Schristos 					keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret );
55678d5fdc3Schristos 					if (keylen < 0) { free(authInfo); err = 1; goto exit; }
55778d5fdc3Schristos 
55878d5fdc3Schristos 					authInfo->next = zone->queryKeys;
55978d5fdc3Schristos 					zone->queryKeys = authInfo;
56078d5fdc3Schristos 
56178d5fdc3Schristos 					found = mDNStrue;
56278d5fdc3Schristos 
56378d5fdc3Schristos 					break;
56478d5fdc3Schristos 					}
56578d5fdc3Schristos 				}
56678d5fdc3Schristos 
56778d5fdc3Schristos 			// Log this
56878d5fdc3Schristos 			require_action( found, exit, err = 1 );
56978d5fdc3Schristos 			}
57078d5fdc3Schristos 		}
57178d5fdc3Schristos 
57278d5fdc3Schristos exit:
57378d5fdc3Schristos 
57478d5fdc3Schristos 	return err;
57578d5fdc3Schristos 	}
57678d5fdc3Schristos 
57778d5fdc3Schristos 
57878d5fdc3Schristos void
SetupOptions(OptionsInfo * info,void * context)57978d5fdc3Schristos SetupOptions
58078d5fdc3Schristos 	(
58178d5fdc3Schristos 	OptionsInfo	*	info,
58278d5fdc3Schristos 	void		*	context
58378d5fdc3Schristos 	)
58478d5fdc3Schristos 	{
58578d5fdc3Schristos 	DaemonInfo * d = ( DaemonInfo* ) context;
58678d5fdc3Schristos 
58778d5fdc3Schristos 	if ( strlen( info->source_address ) )
58878d5fdc3Schristos 		{
58978d5fdc3Schristos 		inet_pton( AF_INET, info->source_address, &d->addr.sin_addr );
59078d5fdc3Schristos 		}
59178d5fdc3Schristos 
59278d5fdc3Schristos 	if ( info->source_port )
59378d5fdc3Schristos 		{
59478d5fdc3Schristos 		d->addr.sin_port = htons( ( mDNSu16 ) info->source_port );
59578d5fdc3Schristos 		}
59678d5fdc3Schristos 
59778d5fdc3Schristos 	if ( strlen( info->server_address ) )
59878d5fdc3Schristos 		{
59978d5fdc3Schristos 		inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr );
60078d5fdc3Schristos 		}
60178d5fdc3Schristos 
60278d5fdc3Schristos 	if ( info->server_port )
60378d5fdc3Schristos 		{
60478d5fdc3Schristos 		d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port );
60578d5fdc3Schristos 		}
60678d5fdc3Schristos 
60778d5fdc3Schristos 	if ( info->private_port )
60878d5fdc3Schristos 		{
60978d5fdc3Schristos 		d->private_port = mDNSOpaque16fromIntVal( info->private_port );
61078d5fdc3Schristos 		}
61178d5fdc3Schristos 
61278d5fdc3Schristos 	if ( info->llq_port )
61378d5fdc3Schristos 		{
61478d5fdc3Schristos 		d->llq_port = mDNSOpaque16fromIntVal( info->llq_port );
61578d5fdc3Schristos 		}
61678d5fdc3Schristos 	}
617