diff options
Diffstat (limited to 'mDNSResponder/mDNSShared/dnsextd_parser.y')
-rw-r--r-- | mDNSResponder/mDNSShared/dnsextd_parser.y | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSShared/dnsextd_parser.y b/mDNSResponder/mDNSShared/dnsextd_parser.y new file mode 100644 index 00000000..18c5990f --- /dev/null +++ b/mDNSResponder/mDNSShared/dnsextd_parser.y @@ -0,0 +1,585 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +%{ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "mDNSEmbeddedAPI.h" +#include "DebugServices.h" +#include "dnsextd.h" + +void yyerror( const char* error ); +int yylex(void); + + +typedef struct StringListElem +{ + char * string; + struct StringListElem * next; +} StringListElem; + + +typedef struct OptionsInfo +{ + char server_address[ 256 ]; + int server_port; + char source_address[ 256 ]; + int source_port; + int private_port; + int llq_port; +} OptionsInfo; + + +typedef struct ZoneInfo +{ + char name[ 256 ]; + char certificate_name[ 256 ]; + char allow_clients_file[ 256 ]; + char allow_clients[ 256 ]; + char key[ 256 ]; +} ZoneInfo; + + +typedef struct KeySpec +{ + char name[ 256 ]; + char algorithm[ 256 ]; + char secret[ 256 ]; + struct KeySpec * next; +} KeySpec; + + +typedef struct ZoneSpec +{ + char name[ 256 ]; + DNSZoneSpecType type; + StringListElem * allowUpdate; + StringListElem * allowQuery; + char key[ 256 ]; + struct ZoneSpec * next; +} ZoneSpec; + + +static StringListElem * g_stringList = NULL; +static KeySpec * g_keys; +static ZoneSpec * g_zones; +static ZoneSpec g_zoneSpec; +static const char * g_filename; + +#define YYPARSE_PARAM context + +void +SetupOptions + ( + OptionsInfo * info, + void * context + ); + +%} + +%union +{ + int number; + char * string; +} + +%token OPTIONS +%token LISTEN_ON +%token NAMESERVER +%token PORT +%token ADDRESS +%token LLQ +%token PUBLIC +%token PRIVATE +%token ALLOWUPDATE +%token ALLOWQUERY +%token KEY +%token ALGORITHM +%token SECRET +%token ISSUER +%token SERIAL +%token ZONE +%token TYPE +%token ALLOW +%token OBRACE +%token EBRACE +%token SEMICOLON +%token IN +%token <string> DOTTED_DECIMAL_ADDRESS +%token <string> WILDCARD +%token <string> DOMAINNAME +%token <string> HOSTNAME +%token <string> QUOTEDSTRING +%token <number> NUMBER + +%type <string> addressstatement +%type <string> networkaddress + +%% + +commands: + | + commands command SEMICOLON + ; + + +command: + options_set + | + zone_set + | + key_set + ; + + +options_set: + OPTIONS optionscontent + { + // SetupOptions( &g_optionsInfo, context ); + } + ; + +optionscontent: + OBRACE optionsstatements EBRACE + ; + +optionsstatements: + | + optionsstatements optionsstatement SEMICOLON + ; + + +optionsstatement: + statements + | + LISTEN_ON addresscontent + { + } + | + LISTEN_ON PORT NUMBER addresscontent + { + } + | + NAMESERVER ADDRESS networkaddress + { + } + | + NAMESERVER ADDRESS networkaddress PORT NUMBER + { + } + | + PRIVATE PORT NUMBER + { + ( ( DaemonInfo* ) context )->private_port = mDNSOpaque16fromIntVal( $3 ); + } + | + LLQ PORT NUMBER + { + ( ( DaemonInfo* ) context )->llq_port = mDNSOpaque16fromIntVal( $3 ); + } + ; + +key_set: + KEY QUOTEDSTRING OBRACE SECRET QUOTEDSTRING SEMICOLON EBRACE + { + KeySpec * keySpec; + + keySpec = ( KeySpec* ) malloc( sizeof( KeySpec ) ); + + if ( !keySpec ) + { + LogMsg("ERROR: memory allocation failure"); + YYABORT; + } + + strncpy( keySpec->name, $2, sizeof( keySpec->name ) ); + strncpy( keySpec->secret, $5, sizeof( keySpec->secret ) ); + + keySpec->next = g_keys; + g_keys = keySpec; + } + ; + +zone_set: + ZONE QUOTEDSTRING zonecontent + { + ZoneSpec * zoneSpec; + + zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) ); + + if ( !zoneSpec ) + { + LogMsg("ERROR: memory allocation failure"); + YYABORT; + } + + strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) ); + zoneSpec->type = g_zoneSpec.type; + strcpy( zoneSpec->key, g_zoneSpec.key ); + zoneSpec->allowUpdate = g_zoneSpec.allowUpdate; + zoneSpec->allowQuery = g_zoneSpec.allowQuery; + + zoneSpec->next = g_zones; + g_zones = zoneSpec; + } + | + ZONE QUOTEDSTRING IN zonecontent + { + ZoneSpec * zoneSpec; + + zoneSpec = ( ZoneSpec* ) malloc( sizeof( ZoneSpec ) ); + + if ( !zoneSpec ) + { + LogMsg("ERROR: memory allocation failure"); + YYABORT; + } + + strncpy( zoneSpec->name, $2, sizeof( zoneSpec->name ) ); + zoneSpec->type = g_zoneSpec.type; + strcpy( zoneSpec->key, g_zoneSpec.key ); + zoneSpec->allowUpdate = g_zoneSpec.allowUpdate; + zoneSpec->allowQuery = g_zoneSpec.allowQuery; + + zoneSpec->next = g_zones; + g_zones = zoneSpec; + } + ; + +zonecontent: + OBRACE zonestatements EBRACE + +zonestatements: + | + zonestatements zonestatement SEMICOLON + ; + +zonestatement: + TYPE PUBLIC + { + g_zoneSpec.type = kDNSZonePublic; + } + | + TYPE PRIVATE + { + g_zoneSpec.type = kDNSZonePrivate; + } + | + ALLOWUPDATE keycontent + { + g_zoneSpec.allowUpdate = g_stringList; + g_stringList = NULL; + } + | + ALLOWQUERY keycontent + { + g_zoneSpec.allowQuery = g_stringList; + g_stringList = NULL; + } + ; + +addresscontent: + OBRACE addressstatements EBRACE + { + } + +addressstatements: + | + addressstatements addressstatement SEMICOLON + { + } + ; + +addressstatement: + DOTTED_DECIMAL_ADDRESS + { + } + ; + + +keycontent: + OBRACE keystatements EBRACE + { + } + +keystatements: + | + keystatements keystatement SEMICOLON + { + } + ; + +keystatement: + KEY DOMAINNAME + { + StringListElem * elem; + + elem = ( StringListElem* ) malloc( sizeof( StringListElem ) ); + + if ( !elem ) + { + LogMsg("ERROR: memory allocation failure"); + YYABORT; + } + + elem->string = $2; + + elem->next = g_stringList; + g_stringList = elem; + } + ; + + +networkaddress: + DOTTED_DECIMAL_ADDRESS + | + HOSTNAME + | + WILDCARD + ; + +block: + OBRACE zonestatements EBRACE SEMICOLON + ; + +statements: + | + statements statement + ; + +statement: + block + { + $<string>$ = NULL; + } + | + QUOTEDSTRING + { + $<string>$ = $1; + } +%% + +int yywrap(void); + +extern int yylineno; + +void yyerror( const char *str ) +{ + fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str ); +} + +int yywrap() +{ + return 1; +} + + +int +ParseConfig + ( + DaemonInfo * d, + const char * file + ) + { + extern FILE * yyin; + DNSZone * zone; + DomainAuthInfo * key; + KeySpec * keySpec; + ZoneSpec * zoneSpec; + int err = 0; + + g_filename = file; + + // Tear down the current zone specifiers + + zone = d->zones; + + while ( zone ) + { + DNSZone * next = zone->next; + + key = zone->updateKeys; + + while ( key ) + { + DomainAuthInfo * nextKey = key->next; + + free( key ); + + key = nextKey; + } + + key = zone->queryKeys; + + while ( key ) + { + DomainAuthInfo * nextKey = key->next; + + free( key ); + + key = nextKey; + } + + free( zone ); + + zone = next; + } + + d->zones = NULL; + + yyin = fopen( file, "r" ); + require_action( yyin, exit, err = 0 ); + + err = yyparse( ( void* ) d ); + require_action( !err, exit, err = 1 ); + + for ( zoneSpec = g_zones; zoneSpec; zoneSpec = zoneSpec->next ) + { + StringListElem * elem; + mDNSu8 * ok; + + zone = ( DNSZone* ) malloc( sizeof( DNSZone ) ); + require_action( zone, exit, err = 1 ); + memset( zone, 0, sizeof( DNSZone ) ); + + zone->next = d->zones; + d->zones = zone; + + // Fill in the domainname + + ok = MakeDomainNameFromDNSNameString( &zone->name, zoneSpec->name ); + require_action( ok, exit, err = 1 ); + + // Fill in the type + + zone->type = zoneSpec->type; + + // Fill in the allow-update keys + + for ( elem = zoneSpec->allowUpdate; elem; elem = elem->next ) + { + mDNSBool found = mDNSfalse; + + for ( keySpec = g_keys; keySpec; keySpec = keySpec->next ) + { + if ( strcmp( elem->string, keySpec->name ) == 0 ) + { + DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) ); + mDNSs32 keylen; + require_action( authInfo, exit, err = 1 ); + memset( authInfo, 0, sizeof( DomainAuthInfo ) ); + + ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name ); + if (!ok) { free(authInfo); err = 1; goto exit; } + + keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret ); + if (keylen < 0) { free(authInfo); err = 1; goto exit; } + + authInfo->next = zone->updateKeys; + zone->updateKeys = authInfo; + + found = mDNStrue; + + break; + } + } + + // Log this + require_action( found, exit, err = 1 ); + } + + // Fill in the allow-query keys + + for ( elem = zoneSpec->allowQuery; elem; elem = elem->next ) + { + mDNSBool found = mDNSfalse; + + for ( keySpec = g_keys; keySpec; keySpec = keySpec->next ) + { + if ( strcmp( elem->string, keySpec->name ) == 0 ) + { + DomainAuthInfo * authInfo = malloc( sizeof( DomainAuthInfo ) ); + mDNSs32 keylen; + require_action( authInfo, exit, err = 1 ); + memset( authInfo, 0, sizeof( DomainAuthInfo ) ); + + ok = MakeDomainNameFromDNSNameString( &authInfo->keyname, keySpec->name ); + if (!ok) { free(authInfo); err = 1; goto exit; } + + keylen = DNSDigest_ConstructHMACKeyfromBase64( authInfo, keySpec->secret ); + if (keylen < 0) { free(authInfo); err = 1; goto exit; } + + authInfo->next = zone->queryKeys; + zone->queryKeys = authInfo; + + found = mDNStrue; + + break; + } + } + + // Log this + require_action( found, exit, err = 1 ); + } + } + +exit: + + return err; + } + + +void +SetupOptions + ( + OptionsInfo * info, + void * context + ) + { + DaemonInfo * d = ( DaemonInfo* ) context; + + if ( strlen( info->source_address ) ) + { + inet_pton( AF_INET, info->source_address, &d->addr.sin_addr ); + } + + if ( info->source_port ) + { + d->addr.sin_port = htons( ( mDNSu16 ) info->source_port ); + } + + if ( strlen( info->server_address ) ) + { + inet_pton( AF_INET, info->server_address, &d->ns_addr.sin_addr ); + } + + if ( info->server_port ) + { + d->ns_addr.sin_port = htons( ( mDNSu16 ) info->server_port ); + } + + if ( info->private_port ) + { + d->private_port = mDNSOpaque16fromIntVal( info->private_port ); + } + + if ( info->llq_port ) + { + d->llq_port = mDNSOpaque16fromIntVal( info->llq_port ); + } + } |