From: Francis Dupont Date: Wed, 24 Mar 2021 16:22:54 +0000 (+0100) Subject: [#1663] Checkpoint X-Git-Tag: Kea-1.9.6~85 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=00fbf6141b2c720bb5d1b7ef5def580b7a075424;p=thirdparty%2Fkea.git [#1663] Checkpoint --- diff --git a/doc/sphinx/man/kea-shell.8.rst b/doc/sphinx/man/kea-shell.8.rst index 00e341d852..012497f3be 100644 --- a/doc/sphinx/man/kea-shell.8.rst +++ b/doc/sphinx/man/kea-shell.8.rst @@ -1,5 +1,5 @@ .. - Copyright (C) 2019-2020 Internet Systems Consortium, Inc. ("ISC") + Copyright (C) 2019-2021 Internet Systems Consortium, Inc. ("ISC") This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this @@ -15,7 +15,7 @@ kea-shell - Text client for Control Agent process Synopsis ~~~~~~~~ -:program:`kea-shell` [**-h**] [**-v**] [**--host**] [**--port**] [**--path**] [**--auth-user**] [**--auth-password**] [**--timeout**] [**--service**] [command] +:program:`kea-shell` [**-h**] [**-v**] [**--host**] [**--port**] [**--path**] [**--ca**] [**--cert**] [**--key**] [**--auth-user**] [**--auth-password**] [**--timeout**] [**--service**] [command] Description ~~~~~~~~~~~ @@ -24,7 +24,9 @@ The ``kea-shell`` provides a REST client for the Kea Control Agent (CA). It takes command as a command-line parameter that is being sent to CA with proper JSON encapsulation. Optional arguments may be specified on the standard input. The request is sent via HTTP and a response is -retrieved, displayed on the standard output. +retrieved, displayed on the standard output. Basic HTTP authentication +and HTTPS i.e. TLS transport are supported. + Arguments ~~~~~~~~~ @@ -50,6 +52,19 @@ The arguments are as follows: path is used. As Control Agent listens at the empty path, this parameter is useful only with a reverse proxy. +``--ca`` + Specifies the file or directory name of the Cerfication Authority. + If not specified HTTPS is not used. + +``--cert`` + Specifies the file name of the user end-entity public key certificate. + If specified the file name of the user key must be specified too. + +``--key`` + Specifies the file name of the user key file. If specified the file + name of the user certificate must be specified too. Note that + encrypted key file are not supported. + ``--auth-user`` Specifies the user id for basic HTTP authentication. If not specified or specified as the empty string authentication is not used. diff --git a/src/bin/shell/kea-shell.in b/src/bin/shell/kea-shell.in index a9b73edeef..9dbd79c185 100644 --- a/src/bin/shell/kea-shell.in +++ b/src/bin/shell/kea-shell.in @@ -67,6 +67,15 @@ def shell_body(): parser.add_argument('--path', type=str, default='', help='Path of the URL to connect to ' '(default: "")') + parser.add_argument('--ca', type=str, default='', + help='File or directory name of the CA ' + '(default: "" i.e. do not use HTTPS)') + parser.add_argument('--cert', type=str, default='', + help='File name of the client certificate ' + '(default: "" i.e. do not use HTTPS)') + parser.add_argument('--key', type=str, default='', + help='File name of the client private key ' + '(default: "" i.e. do not use HTTPS)') parser.add_argument('--timeout', type=int, default='10', help='Timeout (in seconds) when attempting to ' 'connect to CA (default: 10)') @@ -96,6 +105,15 @@ def shell_body(): params.http_host = cmd_args.host params.http_port = cmd_args.port params.path += cmd_args.path + if cmd_args.ca: + params.ca = cmd_args.ca + params.scheme = 'https' + if (cmd_args.cert != '' and cmd_args.key == '') or \ + (cmd_args.cert == '' and cmd_args.key != ''): + print("--cert and --key must be used together") + sys.exit(1) + if cmd_args.cert: + params.cert = (cmd_args.cert, cmd_args.key) if cmd_args.auth_user != '': user = cmd_args.auth_user password = cmd_args.auth_password diff --git a/src/bin/shell/kea_conn.py b/src/bin/shell/kea_conn.py index d8c54aa48a..de6ad5786b 100644 --- a/src/bin/shell/kea_conn.py +++ b/src/bin/shell/kea_conn.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017-2020 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2017-2021 Internet Systems Consortium, Inc. ("ISC") # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -13,8 +13,11 @@ class CARequest: This class defines the HTTP request to be sent. The supported parameters listed are: - path (specifies the path on the server, CA uses only /) + - scheme - http or https - http_host - hostname of the CA - - http-port - TCP port of the CA + - http_port - TCP port of the CA + - ca - False or CA file or path + - cert - False or cert file or cert and key files pair - command - specifies the command to send (e.g. list-commands) - service - specifies service that is target for the command (e.g. dhcp4) - timeout - timeout (in ms) @@ -24,8 +27,11 @@ class CARequest: - version - version to be reported in HTTP header """ path = '/' + scheme = 'http' http_host = '' http_port = 0 + ca = False + cert = False command = '' service = '' timeout = 0 diff --git a/src/bin/shell/kea_connector3.py b/src/bin/shell/kea_connector3.py index 738ad37f6f..809776bced 100644 --- a/src/bin/shell/kea_connector3.py +++ b/src/bin/shell/kea_connector3.py @@ -1,4 +1,4 @@ -# Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2017-2021 Internet Systems Consortium, Inc. ("ISC") # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,6 +9,8 @@ This is PYTHON 3.x version of HTTP connection establishment """ import urllib.request +import ssl +import os from kea_conn import CAResponse # CARequest @@ -16,7 +18,7 @@ def send_to_control_agent(params): """ Sends a request to Control Agent, receives a response and returns it.""" # First, create the URL - url = "http://" + params.http_host + ":" + url = params.scheme + "://" + params.http_host + ":" url += str(params.http_port) + str(params.path) # Now prepare the request (URL, headers and body) @@ -24,8 +26,22 @@ def send_to_control_agent(params): data=str.encode(params.content), headers=params.headers) + # Set up the SSL context. + ssl_ctx = None + capath = None + cafile = None + if params.ca: + if os.path.isdir(params.ca): + capath = params.ca + else: + cafile = params.ca + ssl_ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) + ssl_ctx.load_verify_locations(cafile, capath) + if params.cert: + ssl_ctx.load_cert_chain(param.cert[0], param.cert[1]) + # Establish connection, send the request. - resp = urllib.request.urlopen(req) + resp = urllib.request.urlopen(req, context=ssl_ctx) # Now get the response details, put it in CAResponse and return it result = CAResponse(resp.getcode(), resp.reason,