diff --git a/src/bin/dhcp4/dhcp4_lexer.ll b/src/bin/dhcp4/dhcp4_lexer.ll index c0eaa45984..e4dc4e73f8 100644 --- a/src/bin/dhcp4/dhcp4_lexer.ll +++ b/src/bin/dhcp4/dhcp4_lexer.ll @@ -401,6 +401,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::OPTION_DEF: case isc::dhcp::Parser4Context::CONFIG_DATABASE: + case isc::dhcp::Parser4Context::AUTH_TYPE: return isc::dhcp::Dhcp4Parser::make_TYPE(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("type", driver.loc_); @@ -439,6 +440,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] case isc::dhcp::Parser4Context::LEASE_DATABASE: case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::CONFIG_DATABASE: + case isc::dhcp::Parser4Context::CLIENTS: return isc::dhcp::Dhcp4Parser::make_USER(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("user", driver.loc_); @@ -450,6 +452,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] case isc::dhcp::Parser4Context::LEASE_DATABASE: case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::CONFIG_DATABASE: + case isc::dhcp::Parser4Context::CLIENTS: return isc::dhcp::Dhcp4Parser::make_PASSWORD(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("password", driver.loc_); @@ -629,6 +632,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] case isc::dhcp::Parser4Context::LEASE_DATABASE: case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::CONFIG_DATABASE: + case isc::dhcp::Parser4Context::CONTROL_SOCKET: return isc::dhcp::Dhcp4Parser::make_TRUST_ANCHOR(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("trust-anchor", driver.loc_); @@ -640,6 +644,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] case isc::dhcp::Parser4Context::LEASE_DATABASE: case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::CONFIG_DATABASE: + case isc::dhcp::Parser4Context::CONTROL_SOCKET: return isc::dhcp::Dhcp4Parser::make_CERT_FILE(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("cert-file", driver.loc_); @@ -651,6 +656,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] case isc::dhcp::Parser4Context::LEASE_DATABASE: case isc::dhcp::Parser4Context::HOSTS_DATABASE: case isc::dhcp::Parser4Context::CONFIG_DATABASE: + case isc::dhcp::Parser4Context::CONTROL_SOCKET: return isc::dhcp::Dhcp4Parser::make_KEY_FILE(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("key-file", driver.loc_); @@ -1671,6 +1677,15 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } +\"control-sockets\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::DHCP4: + return isc::dhcp::Dhcp4Parser::make_CONTROL_SOCKETS(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("control-sockets", driver.loc_); + } +} + \"socket-type\" { switch(driver.ctx_) { case isc::dhcp::Parser4Context::CONTROL_SOCKET: @@ -1680,6 +1695,33 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } +\"unix\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET_TYPE: + return isc::dhcp::Dhcp4Parser::make_UNIX(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("unix", driver.loc_); + } +} + +\"http\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET_TYPE: + return isc::dhcp::Dhcp4Parser::make_HTTP(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("http", driver.loc_); + } +} + +\"https\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET_TYPE: + return isc::dhcp::Dhcp4Parser::make_HTTPS(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("https", driver.loc_); + } +} + \"socket-name\" { switch(driver.ctx_) { case isc::dhcp::Parser4Context::CONTROL_SOCKET: @@ -1689,6 +1731,96 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } +\"socket-address\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET: + return isc::dhcp::Dhcp4Parser::make_SOCKET_ADDRESS(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("socket-address", driver.loc_); + } +} + +\"socket-port\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET: + return isc::dhcp::Dhcp4Parser::make_SOCKET_PORT(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("socket-port", driver.loc_); + } +} + +\"authentication\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET: + return isc::dhcp::Dhcp4Parser::make_AUTHENTICATION(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("authentication", driver.loc_); + } +} + +\"basic\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::AUTH_TYPE: + return isc::dhcp::Dhcp4Parser::make_BASIC(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("basic", driver.loc_); + } +} + +\"realm\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::AUTHENTICATION: + return isc::dhcp::Dhcp4Parser::make_REALM(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("realm", driver.loc_); + } +} + +\"directory\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::AUTHENTICATION: + return isc::dhcp::Dhcp4Parser::make_DIRECTORY(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("directory", driver.loc_); + } +} + +\"clients\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::AUTHENTICATION: + return isc::dhcp::Dhcp4Parser::make_CLIENTS(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("clients", driver.loc_); + } +} + +\"user-file\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CLIENTS: + return isc::dhcp::Dhcp4Parser::make_USER_FILE(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("user-file", driver.loc_); + } +} + +\"password-file\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CLIENTS: + return isc::dhcp::Dhcp4Parser::make_PASSWORD_FILE(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("password-file", driver.loc_); + } +} + +\"cert-required\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::CONTROL_SOCKET: + return isc::dhcp::Dhcp4Parser::make_CERT_REQUIRED(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("cert-required", driver.loc_); + } +} + \"dhcp-queue-control\" { switch(driver.ctx_) { case isc::dhcp::Parser4Context::DHCP4: diff --git a/src/bin/dhcp4/dhcp4_parser.yy b/src/bin/dhcp4/dhcp4_parser.yy index a0816348ce..183b6f8ed0 100644 --- a/src/bin/dhcp4/dhcp4_parser.yy +++ b/src/bin/dhcp4/dhcp4_parser.yy @@ -221,8 +221,22 @@ using namespace std; PACKET_QUEUE_SIZE "packet-queue-size" CONTROL_SOCKET "control-socket" + CONTROL_SOCKETS "control-sockets" SOCKET_TYPE "socket-type" + UNIX "unix" + HTTP "http" + HTTPS "https" SOCKET_NAME "socket-name" + SOCKET_ADDRESS "socket-address" + SOCKET_PORT "socket-port" + AUTHENTICATION "authentication" + BASIC "basic" + REALM "realm" + DIRECTORY "directory" + CLIENTS "clients" + USER_FILE "user-file" + USER_PASSWORD "user-password" + CERT_REQUIRED "cert-required" DHCP_QUEUE_CONTROL "dhcp-queue-control" ENABLE_QUEUE "enable-queue" @@ -514,6 +528,7 @@ global_param: valid_lifetime | expired_leases_processing | dhcp4o6_port | control_socket + | control_sockets | dhcp_queue_control | dhcp_ddns | echo_client_id @@ -2505,6 +2520,37 @@ control_socket: CONTROL_SOCKET { ctx.leave(); }; +control_sockets: CONTROL_SOCKETS { + ctx.unique("control-sockets", ctx.loc2pos(@1)); + ElementPtr l(new ListElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("control-sockets", l); + ctx.stack_.push_back(l); + ctx.enter(ctx.CONTROL_SOCKET); +} COLON LSQUARE_BRACKET control_socket_list RSQUARE_BRACKET { + ctx.stack_.pop_back(); + ctx.leave(); +}; + +control_socket_list: %empty + | not_empty_control_socket_list + ; + +not_empty_control_socket_list: control_socket_entry + | not_empty_control_socket_list COMMA control_socket_entry + | not_empty_control_socket_list COMMA { + ctx.warnAboutExtraCommas(@2); + } + ; + +control_socket_entry: LCURLY_BRACKET { + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("control-socket", m); + ctx.stack_.push_back(m); +} control_socket_params RCURLY_BRACKET { + ctx.stack_.pop_back(); + ctx.leave(); +}; + control_socket_params: control_socket_param | control_socket_params COMMA control_socket_param | control_socket_params COMMA { @@ -2514,6 +2560,13 @@ control_socket_params: control_socket_param control_socket_param: control_socket_type | control_socket_name + | control_socket_address + | control_socket_port + | authentication + | trust_anchor + | cert_file + | key_file + | cert_required | user_context | comment | unknown_map_entry @@ -2521,13 +2574,18 @@ control_socket_param: control_socket_type control_socket_type: SOCKET_TYPE { ctx.unique("socket-type", ctx.loc2pos(@1)); - ctx.enter(ctx.NO_KEYWORD); -} COLON STRING { - ElementPtr stype(new StringElement($4, ctx.loc2pos(@4))); - ctx.stack_.back()->set("socket-type", stype); + ctx.enter(ctx.CONTROL_SOCKET_TYPE); +} COLON control_socket_type_value { + ctx.stack_.back()->set("socket-type", $4); ctx.leave(); }; +control_socket_type_value: + UNIX { $$ = ElementPtr(new StringElement("unix", ctx.loc2pos(@1))); } + | HTTP { $$ = ElementPtr(new StringElement("http", ctx.loc2pos(@1))); } + | HTTPS { $$ = ElementPtr(new StringElement("https", ctx.loc2pos(@1))); } + ; + control_socket_name: SOCKET_NAME { ctx.unique("socket-name", ctx.loc2pos(@1)); ctx.enter(ctx.NO_KEYWORD); @@ -2537,6 +2595,150 @@ control_socket_name: SOCKET_NAME { ctx.leave(); }; +control_socket_address: SOCKET_ADDRESS { + ctx.unique("socket-address", ctx.loc2pos(@1)); + ctx.enter(ctx.NO_KEYWORD); +} COLON STRING { + ElementPtr address(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("socket-address", address); + ctx.leave(); +}; + +control_socket_port: SOCKET_PORT COLON INTEGER { + ctx.unique("socket-port", ctx.loc2pos(@1)); + ElementPtr port(new StringElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("socket-port", port); +}; + +cert_required: CERT_REQUIRED COLON BOOLEAN { + ctx.unique("cert-required", ctx.loc2pos(@1)); + ElementPtr req(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("cert-required", req); +}; + +// --- authentication --------------------------------------------- + +authentication: AUTHENTICATION { + ctx.unique("authentication", ctx.loc2pos(@1)); + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("authentication", m); + ctx.stack_.push_back(m); + ctx.enter(ctx.AUTHENTICATION); +} COLON LCURLY_BRACKET auth_params RCURLY_BRACKET { + // The type parameter is required + ctx.require("type", ctx.loc2pos(@4), ctx.loc2pos(@6)); + ctx.stack_.pop_back(); + ctx.leave(); +}; + +auth_params: auth_param + | auth_params COMMA auth_param + | auth_params COMMA { + ctx.warnAboutExtraCommas(@2); + } + ; + +auth_param: auth_type + | realm + | directory + | clients + | comment + | user_context + | unknown_map_entry + ; + +auth_type: TYPE { + ctx.unique("type", ctx.loc2pos(@1)); + ctx.enter(ctx.AUTH_TYPE); +} COLON auth_type_value { + ctx.stack_.back()->set("type", $4); + ctx.leave(); +}; + +auth_type_value: BASIC { $$ = ElementPtr(new StringElement("basic", ctx.loc2pos(@1))); } + ; + +realm: REALM { + ctx.unique("realm", ctx.loc2pos(@1)); + ctx.enter(ctx.NO_KEYWORDS); +} COLON STRING { + ElementPtr realm(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("realm", realm); + ctx.leave(); +}; + +directory: DIRECTORY { + ctx.unique("directory", ctx.loc2pos(@1)); + ctx.enter(ctx.NO_KEYWORDS); +} COLON STRING { + ElementPtr directory(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("directory", directory); + ctx.leave(); +}; + +clients: CLIENTS { + ctx.unique("clients", ctx.loc2pos(@1)); + ElementPtr l(new ListElement(ctx.loc2pos(@1))); + ctx.stack_.back()->set("clients", l); + ctx.stack_.push_back(l); + ctx.enter(ctx.CLIENTS); +} COLON LSQUARE_BRACKET clients_list RSQUARE_BRACKET { + ctx.stack_.pop_back(); + ctx.leave(); +}; + +clients_list: %empty + | not_empty_clients_list + ; + +not_empty_clients_list: basic_auth + | not_empty_clients_list COMMA basic_auth + | not_empty_clients_list COMMA { + ctx.warnAboutExtraCommas(@2); + } + ; + +basic_auth: LCURLY_BRACKET { + ElementPtr m(new MapElement(ctx.loc2pos(@1))); + ctx.stack_.back()->add(m); + ctx.stack_.push_back(m); +} clients_params RCURLY_BRACKET { + ctx.stack_.pop_back(); +}; + +clients_params: clients_param + | clients_params COMMA clients_param + | clients_params COMMA { + ctx.warnAboutExtraCommas(@2); + } + ; + +clients_param: user + | user_file + | password + | password_file + | user_context + | comment + | unknown_map_entry + ; + +user_file: USER_FILE { + ctx.unique("user-file", ctx.loc2pos(@1)); + ctx.enter(ctx.NO_KEYWORDS); +} COLON STRING { + ElementPtr user(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("user-file", user); + ctx.leave(); +}; + +password_file: PASSWORD_FILE { + ctx.unique("password-file", ctx.loc2pos(@1)); + ctx.enter(ctx.NO_KEYWORDS); +} COLON STRING { + ElementPtr password(new StringElement($4, ctx.loc2pos(@4))); + ctx.stack_.back()->set("password-file", password); + ctx.leave(); +}; // --- dhcp-queue-control --------------------------------------------- diff --git a/src/bin/dhcp4/parser_context.cc b/src/bin/dhcp4/parser_context.cc index c13d264133..c0156c79bf 100644 --- a/src/bin/dhcp4/parser_context.cc +++ b/src/bin/dhcp4/parser_context.cc @@ -187,6 +187,14 @@ Parser4Context::contextName() { return ("server-id"); case CONTROL_SOCKET: return ("control-socket"); + case CONTROL_SOCKET_TYPE: + return ("control-socket-type"); + case AUTHENTICATION: + return ("authentication"); + case AUTH_TYPE: + return ("auth-type"); + case CLIENTS: + return ("clients"); case DHCP_QUEUE_CONTROL: return ("dhcp-queue-control"); case DHCP_MULTI_THREADING: diff --git a/src/bin/dhcp4/parser_context.h b/src/bin/dhcp4/parser_context.h index d59f4b4765..4e6ff20663 100644 --- a/src/bin/dhcp4/parser_context.h +++ b/src/bin/dhcp4/parser_context.h @@ -293,6 +293,20 @@ public: /// Used while parsing Dhcp4/control-socket structures. CONTROL_SOCKET, + /// Used while parsing Dhcp4/control-socket/socket-type structures. + CONTROL_SOCKET_TYPE, + + /// Used while parsing Dhcp4/control-socket/authentication structures. + AUTHENTICATION, + + /// Used while parsing Dhcp4/control-socket/authentication/type + /// structures. + AUTH_TYPE, + + /// Used while parsing Dhcp4/control-socket/authentication/clients + /// structures. + CLIENTS, + /// Used while parsing Dhcp4/dhcp-queue-control structures. DHCP_QUEUE_CONTROL,