blob: e7533f47693aeefeee15d495a1d62ddb90b79148 [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From f05f5fc363e2510f6943532f3e14a6423f6a2cf1 Mon Sep 17 00:00:00 2001
Brad Bishopd7bf8c12018-02-25 22:55:05 -05002From: Hongxu Jia <hongxu.jia@windriver.com>
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08003Date: Tue, 31 Jul 2018 17:24:47 +0800
Brad Bishopd7bf8c12018-02-25 22:55:05 -05004Subject: [PATCH 1/4] support authentication for kickstart
5
6While download kickstart file from web server,
7we support basic/digest authentication.
8
9Add KickstartAuthError to report authentication failure,
10which the invoker could parse this specific error.
11
12Upstream-Status: inappropriate [oe specific]
13
14Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
15---
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080016 pykickstart/errors.py | 17 +++++++++++++++++
17 pykickstart/load.py | 34 ++++++++++++++++++++++++++++------
Brad Bishopd7bf8c12018-02-25 22:55:05 -050018 pykickstart/parser.py | 4 ++--
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080019 3 files changed, 47 insertions(+), 8 deletions(-)
Brad Bishopd7bf8c12018-02-25 22:55:05 -050020
21diff --git a/pykickstart/errors.py b/pykickstart/errors.py
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080022index bf08ac5..aada7aa 100644
Brad Bishopd7bf8c12018-02-25 22:55:05 -050023--- a/pykickstart/errors.py
24+++ b/pykickstart/errors.py
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080025@@ -32,6 +32,9 @@ This module exports several exception classes:
Brad Bishopd7bf8c12018-02-25 22:55:05 -050026 KickstartVersionError - An exception for errors relating to unsupported
27 syntax versions.
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080028
Brad Bishopd7bf8c12018-02-25 22:55:05 -050029+ KickstartAuthError - An exception for errors relating to authentication
30+ failed while downloading kickstart from web server
31+
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080032 And some warning classes:
Brad Bishopd7bf8c12018-02-25 22:55:05 -050033
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080034 KickstartWarning - A generic warning class.
35@@ -131,3 +134,17 @@ class KickstartDeprecationWarning(KickstartParseWarning, DeprecationWarning):
36 commands and options.
37 """
38 pass
Brad Bishopd7bf8c12018-02-25 22:55:05 -050039+
40+class KickstartAuthError(KickstartError):
41+ """An exception for errors relating to authentication failed while
42+ downloading kickstart from web server
43+ """
44+ def __init__(self, msg):
45+ """Create a new KickstartAuthError exception instance with the
46+ descriptive message val. val should be the return value of
47+ formatErrorMsg.
48+ """
49+ KickstartError.__init__(self, msg)
50+
51+ def __str__(self):
52+ return self.value
Brad Bishopd7bf8c12018-02-25 22:55:05 -050053diff --git a/pykickstart/load.py b/pykickstart/load.py
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080054index fb935f2..41a2e9e 100644
Brad Bishopd7bf8c12018-02-25 22:55:05 -050055--- a/pykickstart/load.py
56+++ b/pykickstart/load.py
57@@ -18,10 +18,13 @@
58 # with the express permission of Red Hat, Inc.
59 #
60 import requests
61+from requests.auth import HTTPDigestAuth
62+from requests.auth import HTTPBasicAuth
63+
64 import shutil
65 import six
66
67-from pykickstart.errors import KickstartError
68+from pykickstart.errors import KickstartError, KickstartAuthError
69 from pykickstart.i18n import _
70 from requests.exceptions import SSLError, RequestException
71
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080072@@ -29,7 +32,7 @@ _is_url = lambda location: '://' in location # RFC 3986
Brad Bishopd7bf8c12018-02-25 22:55:05 -050073
74 SSL_VERIFY = True
75
76-def load_to_str(location):
77+def load_to_str(location, user=None, passwd=None):
78 '''Load a destination URL or file into a string.
79 Type of input is inferred automatically.
80
81@@ -40,7 +43,7 @@ def load_to_str(location):
82 Raises: KickstartError on error reading'''
83
84 if _is_url(location):
85- return _load_url(location)
86+ return _load_url(location, user=user, passwd=passwd)
87 else:
88 return _load_file(location)
89
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080090@@ -70,11 +73,30 @@ def load_to_file(location, destination):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050091 _copy_file(location, destination)
92 return destination
93
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080094-def _load_url(location):
95- '''Load a location (URL or filename) and return contents as string'''
Brad Bishopd7bf8c12018-02-25 22:55:05 -050096+def _get_auth(location, user=None, passwd=None):
97+
98+ auth = None
99+ request = requests.get(location, verify=SSL_VERIFY)
100+ if request.status_code == requests.codes.unauthorized:
101+ if user is None or passwd is None:
102+ log.info("Require Authentication")
103+ raise KickstartAuthError("Require Authentication.\nAppend 'ksuser=<username> kspasswd=<password>' to boot command")
104
105+ reasons = request.headers.get("WWW-Authenticate", "").split()
106+ if reasons:
107+ auth_type = reasons[0]
108+ if auth_type == "Basic":
109+ auth = HTTPBasicAuth(user, passwd)
110+ elif auth_type == "Digest":
111+ auth=HTTPDigestAuth(user, passwd)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800112+
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500113+ return auth
114+
115+def _load_url(location, user=None, passwd=None):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800116+ '''Load a location (URL or filename) and return contents as string'''
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500117+ auth = _get_auth(location, user=user, passwd=passwd)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500118 try:
119- request = requests.get(location, verify=SSL_VERIFY)
120+ request = requests.get(location, verify=SSL_VERIFY, auth=auth)
121 except SSLError as e:
122 raise KickstartError(_('Error securely accessing URL "%s"') % location + ': {e}'.format(e=str(e)))
123 except RequestException as e:
124diff --git a/pykickstart/parser.py b/pykickstart/parser.py
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800125index d8880eb..22d14cb 100644
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500126--- a/pykickstart/parser.py
127+++ b/pykickstart/parser.py
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800128@@ -787,7 +787,7 @@ class KickstartParser(object):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500129 i = PutBackIterator(s.splitlines(True) + [""])
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800130 self._stateMachine(i)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500131
132- def readKickstart(self, f, reset=True):
133+ def readKickstart(self, f, reset=True, username=None, password=None):
134 """Process a kickstart file, given by the filename f."""
135 if reset:
136 self._reset()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800137@@ -808,7 +808,7 @@ class KickstartParser(object):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500138 self.currentdir[self._includeDepth] = cd
139
140 try:
141- s = load_to_str(f)
142+ s = load_to_str(f, user=username, passwd=password)
143 except KickstartError as e:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800144 raise KickstartError(_("Unable to open input kickstart file: %s") % str(e), lineno=0)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500145
146--
1472.7.4
148