]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1663] Checkpoint
authorFrancis Dupont <fdupont@isc.org>
Wed, 24 Mar 2021 16:22:54 +0000 (17:22 +0100)
committerFrancis Dupont <fdupont@isc.org>
Thu, 25 Mar 2021 08:31:33 +0000 (09:31 +0100)
doc/sphinx/man/kea-shell.8.rst
src/bin/shell/kea-shell.in
src/bin/shell/kea_conn.py
src/bin/shell/kea_connector3.py

index 00e341d85247a5a29b7c7067dc5897ee32634595..012497f3be5cbbac2880cad5f20eef1601eb7261 100644 (file)
@@ -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.
index a9b73edeef3bab221824b64453b4dae934f722d8..9dbd79c18584ff3dec1f2124a1119810708ebef6 100644 (file)
@@ -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
index d8c54aa48a30c258457808d58710c1910866f9bc..de6ad5786b91e26c125f9c4713f14c5285e52ac9 100644 (file)
@@ -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
index 738ad37f6f9dd1fca3c5557c088c87ef3ba5c429..809776bced148f4c6b4463e1bef1404f02264638 100644 (file)
@@ -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,