Kea: unix_command_config.cc Source File

| Kea 3.0.3-git

unix_command_config.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <asiolink/io_asio_socket.h>
10#include <cc/dhcp_config_error.h>
11#include <config/command_mgr.h>
12#include <config/unix_command_config.h>
13#include <util/filesystem.h>
14#include <limits>
15
16using namespace isc;
17using namespace isc::asiolink;
18using namespace isc::config;
19using namespace isc::data;
20using namespace isc::dhcp;
21using namespace isc::util::file;
22using namespace std;
23
24namespace isc {
25namespace config {
26
27namespace {
28 // Singleton PathChecker to set and hold valid unix socket path.
29 PathCheckerPtr socket_path_checker_;
30};
31
32const mode_t UnixCommandConfig::DEFAULT_SOCKET_PATH_PERMS = (S_IRWXU | S_IRGRP | S_IXGRP);
33
34mode_t UnixCommandConfig::socket_path_perms_ = UnixCommandConfig::DEFAULT_SOCKET_PATH_PERMS;
35
36UnixCommandConfig::UnixCommandConfig(ConstElementPtr config)
37 : socket_type_("unix"), socket_name_() {
38 if (config->getType() != Element::map) {
39 isc_throw(DhcpConfigError, "expected map type ("
40 << config->getPosition() << ")");
41 }
42 // Get socket type.
43 ConstElementPtr socket_type = config->get("socket-type");
44 if (socket_type) {
45 if (socket_type->getType() != Element::string) {
46 isc_throw(DhcpConfigError,
47 "invalid type specified for parameter 'socket-type' ("
48 << socket_type->getPosition() << ")");
49 }
50 socket_type_ = socket_type->stringValue();
51 if ((socket_type_ != "unix")) {
52 isc_throw(DhcpConfigError, "unsupported 'socket-type' '"
53 << socket_type_ << "' not 'unix'");
54 }
55 }
56 // Reject HTTP/HTTPS only socket-address.
57 if (config->contains("socket-address")) {
58 isc_throw(DhcpConfigError,
59 "parameter 'socket-address' is not supported by UNIX "
60 "control sockets");
61 }
62 // Get socket name.
63 ConstElementPtr socket_name = config->get("socket-name");
64 if (!socket_name) {
65 isc_throw(DhcpConfigError, "Mandatory 'socket-name' parameter missing");
66 }
67
68 if (socket_name->getType() != Element::string) {
69 isc_throw(DhcpConfigError,
70 "invalid type specified for parameter 'socket-name' ("
71 << socket_name->getPosition() << ")");
72 }
73
74 try {
75 socket_name_ = validatePath(socket_name->stringValue());
76 } catch (const std::exception& ex) {
77 isc_throw(DhcpConfigError, "'socket-name' is invalid: " << ex.what());
78 }
79
80 // Get user context.
81 ConstElementPtr user_context = config->get("user-context");
82 if (user_context) {
83 setContext(user_context);
84 }
85}
86
87 ElementPtr
88UnixCommandConfig::toElement() const {
89 ElementPtr result = Element::createMap();
90 // Set user-context.
91 contextToElement(result);
92 // Set socket type.
93 result->set("socket-type", Element::create(socket_type_));
94 // Set socket name.
95 result->set("socket-name", Element::create(socket_name_));
96 return (result);
97}
98
99std::string
100UnixCommandConfig::getSocketPath(bool reset /* = false */,
101 const std::string explicit_path /* = "" */) {
102 if (!socket_path_checker_ || reset) {
103 socket_path_checker_.reset(new PathChecker(CONTROL_SOCKET_DIR,
104 "KEA_CONTROL_SOCKET_DIR"));
105 if (!explicit_path.empty()) {
106 socket_path_checker_->getPath(true, explicit_path);
107 }
108 }
109
110 return (socket_path_checker_->getPath());
111}
112
113std::string
114UnixCommandConfig::validatePath(const std::string socket_path) {
115 if (!socket_path_checker_) {
116 getSocketPath();
117 }
118
119 auto valid_path = socket_path_checker_->validatePath(socket_path);
120 auto parent_path = socket_path_checker_->getPath();
121 auto parent_perms = getPermissions(parent_path);
122 if ((parent_perms & ~socket_path_perms_) != 0) {
123 isc_throw (DhcpConfigError,
124 "socket path:" << parent_path
125 << " does not exist or has more relaxed permissions than "
126 << std::oct << socket_path_perms_);
127 }
128
129 return (valid_path);
130}
131
132mode_t
133UnixCommandConfig::getSocketPathPerms() {
134 return (socket_path_perms_);
135}
136
137void
138UnixCommandConfig::setSocketPathPerms(mode_t perms
139 /* = DEFAULT_SOCKET_PATH_PERMS */) {
140 socket_path_perms_ = perms;
141}
142
143} // end of isc::config
144} // end of isc
if
if(!(yy_init))
Definition agent_lexer.cc:1900
Element::create
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:299
Element::map
@ map
Definition data.h:160
Element::string
@ string
Definition data.h:157
Element::createMap
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:354
isc::config::UnixCommandConfig::getSocketPath
static std::string getSocketPath(bool reset=false, const std::string explicit_path="")
Fetches the supported control socket path.
Definition unix_command_config.cc:100
isc::config::UnixCommandConfig::getSocketPathPerms
static mode_t getSocketPathPerms()
Fetches the required socket path permissions mask.
Definition unix_command_config.cc:133
isc::config::UnixCommandConfig::UnixCommandConfig
UnixCommandConfig(isc::data::ConstElementPtr config)
Constructor.
Definition unix_command_config.cc:36
isc::config::UnixCommandConfig::DEFAULT_SOCKET_PATH_PERMS
static const mode_t DEFAULT_SOCKET_PATH_PERMS
Defines the default permissions for unix socket parent directory.
Definition unix_command_config.h:26
isc::config::UnixCommandConfig::setSocketPathPerms
static void setSocketPathPerms(mode_t perms=DEFAULT_SOCKET_PATH_PERMS)
Sets the required socket path permissions mask.
Definition unix_command_config.cc:138
isc::config::UnixCommandConfig::toElement
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition unix_command_config.cc:88
isc::config::UnixCommandConfig::validatePath
static std::string validatePath(const std::string socket_path)
Validates a path against the supported path for unix control sockets.
Definition unix_command_config.cc:114
isc::config::UnixCommandConfig::socket_path_perms_
static mode_t socket_path_perms_
Stores the default permissions for unix socket parent directory.
Definition unix_command_config.h:29
isc::dhcp::DhcpConfigError
To be removed. Please use ConfigError instead.
Definition dhcp_config_error.h:58
isc::util::file::PathChecker
Embodies a supported path against which file paths can be validated.
Definition filesystem.h:195
command_mgr.h
dhcp_config_error.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
filesystem.h
io_asio_socket.h
isc::asiolink
Definition addr_utilities.cc:170
isc::config
Definition command_interpreter.cc:23
isc::data
Definition base_stamped_element.cc:12
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
isc::data::ElementPtr
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::util::file
Definition filesystem.cc:28
isc::util::file::PathCheckerPtr
boost::shared_ptr< PathChecker > PathCheckerPtr
Defines a pointer to a PathChecker.
Definition filesystem.h:314
isc::util::file::getPermissions
mode_t getPermissions(const std::string path)
Fetches the file permissions mask.
Definition filesystem.cc:55
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
isc::data::UserContext::contextToElement
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition user_context.cc:15
isc::data::UserContext::setContext
void setContext(const data::ConstElementPtr &ctx)
Sets user context.
Definition user_context.h:30
unix_command_config.h