summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSShared/dnsextd_parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSShared/dnsextd_parser.y')
-rw-r--r--mDNSResponder/mDNSShared/dnsextd_parser.y585
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 );
+ }
+ }