mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add cluster config settings
This commit is contained in:
parent
ade2eaa057
commit
8764aa9eea
11 changed files with 572 additions and 361 deletions
|
@ -55,7 +55,10 @@ class ReqServerChannel:
|
|||
def __init__(self, opts, transport):
|
||||
self.opts = opts
|
||||
self.transport = transport
|
||||
self.event = None
|
||||
self.event = salt.utils.event.get_master_event(
|
||||
self.opts, self.opts["sock_dir"], listen=False
|
||||
)
|
||||
self.master_key = salt.crypt.MasterKeys(self.opts)
|
||||
|
||||
def pre_fork(self, process_manager):
|
||||
"""
|
||||
|
@ -187,7 +190,10 @@ class ReqServerChannel:
|
|||
The server equivalent of ReqChannel.crypted_transfer_decode_dictentry
|
||||
"""
|
||||
# encrypt with a specific AES key
|
||||
pubfn = os.path.join(self.opts["pki_dir"], "minions", target)
|
||||
if self.master_key.cluster_key:
|
||||
pubfn = os.path.join(self.opts["cluster_pki_dir"], "minions", target)
|
||||
else:
|
||||
pubfn = os.path.join(self.opts["pki_dir"], "minions", target)
|
||||
key = salt.crypt.Crypticle.generate_key_string()
|
||||
pcrypt = salt.crypt.Crypticle(self.opts, key)
|
||||
try:
|
||||
|
@ -212,10 +218,9 @@ class ReqServerChannel:
|
|||
tosign = salt.payload.dumps(
|
||||
{"key": pret["key"], "pillar": ret, "nonce": nonce}
|
||||
)
|
||||
master_pem_path = os.path.join(self.opts["pki_dir"], "master.pem")
|
||||
signed_msg = {
|
||||
"data": tosign,
|
||||
"sig": salt.crypt.sign_message(master_pem_path, tosign),
|
||||
"sig": salt.crypt.sign_message(self.master_key.rsa_path, tosign),
|
||||
}
|
||||
pret[dictkey] = pcrypt.dumps(signed_msg)
|
||||
else:
|
||||
|
@ -223,12 +228,11 @@ class ReqServerChannel:
|
|||
return pret
|
||||
|
||||
def _clear_signed(self, load):
|
||||
master_pem_path = os.path.join(self.opts["pki_dir"], "master.pem")
|
||||
tosign = salt.payload.dumps(load)
|
||||
return {
|
||||
"enc": "clear",
|
||||
"load": tosign,
|
||||
"sig": salt.crypt.sign_message(master_pem_path, tosign),
|
||||
"sig": salt.crypt.sign_message(self.master_key.rsa_path, tosign),
|
||||
}
|
||||
|
||||
def _update_aes(self):
|
||||
|
@ -326,18 +330,21 @@ class ReqServerChannel:
|
|||
else:
|
||||
return {"enc": "clear", "load": {"ret": "full"}}
|
||||
|
||||
pki_dir = self.opts["pki_dir"]
|
||||
if self.opts["cluster_id"]:
|
||||
if self.opts["cluster_pki_dir"]:
|
||||
pki_dir = self.opts["cluster_pki_dir"]
|
||||
|
||||
# Check if key is configured to be auto-rejected/signed
|
||||
auto_reject = self.auto_key.check_autoreject(load["id"])
|
||||
auto_sign = self.auto_key.check_autosign(
|
||||
load["id"], load.get("autosign_grains", None)
|
||||
)
|
||||
|
||||
pubfn = os.path.join(self.opts["pki_dir"], "minions", load["id"])
|
||||
pubfn_pend = os.path.join(self.opts["pki_dir"], "minions_pre", load["id"])
|
||||
pubfn_rejected = os.path.join(
|
||||
self.opts["pki_dir"], "minions_rejected", load["id"]
|
||||
)
|
||||
pubfn_denied = os.path.join(self.opts["pki_dir"], "minions_denied", load["id"])
|
||||
pubfn = os.path.join(pki_dir, "minions", load["id"])
|
||||
pubfn_pend = os.path.join(pki_dir, "minions_pre", load["id"])
|
||||
pubfn_rejected = os.path.join(pki_dir, "minions_rejected", load["id"])
|
||||
pubfn_denied = os.path.join(pki_dir, "minions_denied", load["id"])
|
||||
if self.opts["open_mode"]:
|
||||
# open mode is turned on, nuts to checks and overwrite whatever
|
||||
# is there
|
||||
|
@ -740,6 +747,7 @@ class PubServerChannel:
|
|||
self.event = salt.utils.event.get_event("master", opts=self.opts, listen=False)
|
||||
self.ckminions = salt.utils.minions.CkMinions(self.opts)
|
||||
self.present = {}
|
||||
self.master_key = salt.crypt.MasterKeys(self.opts)
|
||||
|
||||
def close(self):
|
||||
self.transport.close()
|
||||
|
@ -771,6 +779,7 @@ class PubServerChannel:
|
|||
secrets = kwargs.get("secrets", None)
|
||||
if secrets is not None:
|
||||
salt.master.SMaster.secrets = secrets
|
||||
self.master_key = salt.crypt.MasterKeys(self.opts)
|
||||
self.transport.publish_daemon(
|
||||
self.publish_payload, self.presence_callback, self.remove_presence_callback
|
||||
)
|
||||
|
@ -861,9 +870,10 @@ class PubServerChannel:
|
|||
)
|
||||
payload["load"] = crypticle.dumps(load)
|
||||
if self.opts["sign_pub_messages"]:
|
||||
master_pem_path = os.path.join(self.opts["pki_dir"], "master.pem")
|
||||
log.debug("Signing data packet")
|
||||
payload["sig"] = salt.crypt.sign_message(master_pem_path, payload["load"])
|
||||
payload["sig"] = salt.crypt.sign_message(
|
||||
self.master_key.rsa_path, payload["load"]
|
||||
)
|
||||
int_payload = {"payload": salt.payload.dumps(payload)}
|
||||
|
||||
# If topics are upported, target matching has to happen master side
|
||||
|
|
|
@ -153,12 +153,35 @@ class Master(
|
|||
self.config["syndic_dir"],
|
||||
self.config["sqlite_queue_dir"],
|
||||
]
|
||||
pki_dir = self.config["pki_dir"]
|
||||
if (
|
||||
self.config["cluster_pki_dir"]
|
||||
and self.config["cluster_pki_dir"] != self.config["pki_dir"]
|
||||
):
|
||||
v_dirs.extend(
|
||||
[
|
||||
self.config["cluster_pki_dir"],
|
||||
os.path.join(self.config["cluster_pki_dir"], "minions"),
|
||||
os.path.join(self.config["cluster_pki_dir"], "minions_pre"),
|
||||
os.path.join(
|
||||
self.config["cluster_pki_dir"], "minions_denied"
|
||||
),
|
||||
os.path.join(
|
||||
self.config["cluster_pki_dir"], "minions_autosign"
|
||||
),
|
||||
os.path.join(
|
||||
self.config["cluster_pki_dir"], "minions_rejected"
|
||||
),
|
||||
]
|
||||
)
|
||||
pki_dir = [self.config["pki_dir"], self.config["cluster_pki_dir"]]
|
||||
|
||||
verify_env(
|
||||
v_dirs,
|
||||
self.config["user"],
|
||||
permissive=self.config["permissive_pki_access"],
|
||||
root_dir=self.config["root_dir"],
|
||||
pki_dir=self.config["pki_dir"],
|
||||
pki_dir=pki_dir,
|
||||
)
|
||||
# Clear out syndics from cachedir
|
||||
for syndic_file in os.listdir(self.config["syndic_dir"]):
|
||||
|
|
|
@ -185,6 +185,14 @@ VALID_OPTS = immutabletypes.freeze(
|
|||
"pki_dir": str,
|
||||
# A unique identifier for this daemon
|
||||
"id": str,
|
||||
# When defined we operate this master as a part of a cluster.
|
||||
"cluster_id": str,
|
||||
# Defines the other masters in the cluster.
|
||||
"cluster_peers": list,
|
||||
# Use this location instead of pki dir for cluster. This allows users
|
||||
# to define where minion keys and the cluster private key will be
|
||||
# stored.
|
||||
"cluster_pki_dir": str,
|
||||
# Use a module function to determine the unique identifier. If this is
|
||||
# set and 'id' is not set, it will allow invocation of a module function
|
||||
# to determine the value of 'id'. For simple invocations without function
|
||||
|
@ -409,6 +417,8 @@ VALID_OPTS = immutabletypes.freeze(
|
|||
"permissive_pki_access": bool,
|
||||
# The passphrase of the master's private key
|
||||
"key_pass": (type(None), str),
|
||||
# The passphrase of the master cluster's private key
|
||||
"cluster_key_pass": (type(None), str),
|
||||
# The passphrase of the master's private signing key
|
||||
"signing_key_pass": (type(None), str),
|
||||
# The path to a directory to pull in configuration file includes
|
||||
|
@ -1544,6 +1554,7 @@ DEFAULT_MASTER_OPTS = immutabletypes.freeze(
|
|||
"verify_env": True,
|
||||
"permissive_pki_access": False,
|
||||
"key_pass": None,
|
||||
"cluster_key_pass": None,
|
||||
"signing_key_pass": None,
|
||||
"default_include": "master.d/*.conf",
|
||||
"winrepo_dir": os.path.join(salt.syspaths.BASE_FILE_ROOTS_DIR, "win", "repo"),
|
||||
|
@ -4034,6 +4045,19 @@ def apply_master_config(overrides=None, defaults=None):
|
|||
|
||||
prepend_root_dir(opts, prepend_root_dirs)
|
||||
|
||||
# When a cluster id is defined, make sure the other nessicery bits a
|
||||
# defined.
|
||||
if "cluster_id" not in opts:
|
||||
opts["cluster_id"] = None
|
||||
if opts["cluster_id"] is not None:
|
||||
if not opts.get("cluster_peers", None):
|
||||
opts["cluster_peers"] = []
|
||||
if not opts.get("cluster_pki_dir", None):
|
||||
opts["cluster_pki_dir"] = opts["pki_dir"]
|
||||
else:
|
||||
opts["cluster_peers"] = []
|
||||
opts["cluster_pki_dir"] = None
|
||||
|
||||
# Enabling open mode requires that the value be set to True, and
|
||||
# nothing else!
|
||||
opts["open_mode"] = opts["open_mode"] is True
|
||||
|
|
|
@ -371,11 +371,27 @@ class MasterKeys(dict):
|
|||
def __init__(self, opts):
|
||||
super().__init__()
|
||||
self.opts = opts
|
||||
self.pub_path = os.path.join(self.opts["pki_dir"], "master.pub")
|
||||
self.rsa_path = os.path.join(self.opts["pki_dir"], "master.pem")
|
||||
|
||||
self.master_pub_path = os.path.join(self.opts["pki_dir"], "master.pub")
|
||||
self.master_rsa_path = os.path.join(self.opts["pki_dir"], "master.pem")
|
||||
key_pass = salt.utils.sdb.sdb_get(self.opts["key_pass"], self.opts)
|
||||
self.key = self.__get_keys(passphrase=key_pass)
|
||||
self.master_key = self.__get_keys(passphrase=key_pass)
|
||||
|
||||
self.cluster_pub_path = None
|
||||
self.cluster_rsa_path = None
|
||||
self.cluster_key = None
|
||||
if self.opts["cluster_id"]:
|
||||
self.cluster_pub_path = os.path.join(
|
||||
self.opts["cluster_pki_dir"], "cluster.pub"
|
||||
)
|
||||
self.cluster_rsa_path = os.path.join(
|
||||
self.opts["cluster_pki_dir"], "cluster.pem"
|
||||
)
|
||||
key_pass = salt.utils.sdb.sdb_get(self.opts["cluster_key_pass"], self.opts)
|
||||
self.cluster_key = self.__get_keys(
|
||||
name="cluster",
|
||||
passphrase=key_pass,
|
||||
pki_dir=self.opts["cluster_pki_dir"],
|
||||
)
|
||||
|
||||
self.pub_signature = None
|
||||
|
||||
|
@ -433,15 +449,35 @@ class MasterKeys(dict):
|
|||
def __getstate__(self):
|
||||
return {"opts": self.opts}
|
||||
|
||||
def __get_keys(self, name="master", passphrase=None):
|
||||
@property
|
||||
def key(self):
|
||||
if self.cluster_key:
|
||||
return self.cluster_key
|
||||
return self.master_key
|
||||
|
||||
@property
|
||||
def pub_path(self):
|
||||
if self.cluster_pub_path:
|
||||
return self.cluster_pub_path
|
||||
return self.master_pub_path
|
||||
|
||||
@property
|
||||
def rsa_path(self):
|
||||
if self.cluster_rsa_path:
|
||||
return self.cluster_rsa_path
|
||||
return self.master_rsa_path
|
||||
|
||||
def __get_keys(self, name="master", passphrase=None, pki_dir=None):
|
||||
"""
|
||||
Returns a key object for a key in the pki-dir
|
||||
"""
|
||||
path = os.path.join(self.opts["pki_dir"], name + ".pem")
|
||||
if pki_dir is None:
|
||||
pki_dir = self.opts["pki_dir"]
|
||||
path = os.path.join(pki_dir, name + ".pem")
|
||||
if not os.path.exists(path):
|
||||
log.info("Generating %s keys: %s", name, self.opts["pki_dir"])
|
||||
log.info("Generating %s keys: %s", name, pki_dir)
|
||||
gen_keys(
|
||||
self.opts["pki_dir"],
|
||||
pki_dir,
|
||||
name,
|
||||
self.opts["keysize"],
|
||||
self.opts.get("user"),
|
||||
|
@ -465,7 +501,14 @@ class MasterKeys(dict):
|
|||
Return the string representation of a public key
|
||||
in the pki-directory
|
||||
"""
|
||||
path = os.path.join(self.opts["pki_dir"], name + ".pub")
|
||||
if self.cluster_pub_path:
|
||||
path = self.cluster_pub_path
|
||||
else:
|
||||
path = self.master_pub_path
|
||||
# XXX We should always have a key present when this is called, if not
|
||||
# it's an error.
|
||||
# if not os.path.isfile(path):
|
||||
# raise RuntimeError(f"The key {path} does not exist.")
|
||||
if not os.path.isfile(path):
|
||||
key = self.__get_keys()
|
||||
if HAS_M2:
|
||||
|
@ -476,6 +519,9 @@ class MasterKeys(dict):
|
|||
with salt.utils.files.fopen(path) as rfh:
|
||||
return rfh.read()
|
||||
|
||||
def get_ckey_paths(self):
|
||||
return self.cluster_pub_path, self.cluster_rsa_path
|
||||
|
||||
def get_mkey_paths(self):
|
||||
return self.pub_path, self.rsa_path
|
||||
|
||||
|
|
|
@ -332,7 +332,11 @@ class AutoKey:
|
|||
"""
|
||||
Check a keyid for membership in a autosign directory.
|
||||
"""
|
||||
autosign_dir = os.path.join(self.opts["pki_dir"], "minions_autosign")
|
||||
if self.opts["cluster_id"]:
|
||||
pki_dir = self.opts["cluster_pki_dir"]
|
||||
else:
|
||||
pki_dir = self.opts["pki_dir"]
|
||||
autosign_dir = os.path.join(pki_dir, "minions_autosign")
|
||||
|
||||
# cleanup expired files
|
||||
expire_minutes = self.opts.get("autosign_timeout", 120)
|
||||
|
|
70
salt/key.py
70
salt/key.py
|
@ -309,6 +309,9 @@ class Key:
|
|||
|
||||
def __init__(self, opts, io_loop=None):
|
||||
self.opts = opts
|
||||
self.pki_dir = self.opts["pki_dir"]
|
||||
if self.opts["cluster_id"]:
|
||||
self.pki_dir = self.opts["cluster_pki_dir"]
|
||||
kind = self.opts.get("__role", "") # application kind
|
||||
if kind not in salt.utils.kinds.APPL_KINDS:
|
||||
emsg = f"Invalid application kind = '{kind}'."
|
||||
|
@ -330,11 +333,11 @@ class Key:
|
|||
"""
|
||||
Return the minion keys directory paths
|
||||
"""
|
||||
minions_accepted = os.path.join(self.opts["pki_dir"], self.ACC)
|
||||
minions_pre = os.path.join(self.opts["pki_dir"], self.PEND)
|
||||
minions_rejected = os.path.join(self.opts["pki_dir"], self.REJ)
|
||||
minions_accepted = os.path.join(self.pki_dir, self.ACC)
|
||||
minions_pre = os.path.join(self.pki_dir, self.PEND)
|
||||
minions_rejected = os.path.join(self.pki_dir, self.REJ)
|
||||
|
||||
minions_denied = os.path.join(self.opts["pki_dir"], self.DEN)
|
||||
minions_denied = os.path.join(self.pki_dir, self.DEN)
|
||||
return minions_accepted, minions_pre, minions_rejected, minions_denied
|
||||
|
||||
def _get_key_attrs(self, keydir, keyname, keysize, user):
|
||||
|
@ -342,10 +345,10 @@ class Key:
|
|||
if "gen_keys_dir" in self.opts:
|
||||
keydir = self.opts["gen_keys_dir"]
|
||||
else:
|
||||
keydir = self.opts["pki_dir"]
|
||||
keydir = self.pki_dir
|
||||
if not keyname:
|
||||
if "gen_keys" in self.opts:
|
||||
keyname = self.opts["gen_keys"]
|
||||
keyname = self.pki_dir
|
||||
else:
|
||||
keyname = "minion"
|
||||
if not keysize:
|
||||
|
@ -380,7 +383,7 @@ class Key:
|
|||
return f"Public-key {pub} does not exist"
|
||||
# default to master.pub
|
||||
else:
|
||||
mpub = self.opts["pki_dir"] + "/" + "master.pub"
|
||||
mpub = self.pki_dir + "/" + "master.pub"
|
||||
if os.path.isfile(mpub):
|
||||
pub = mpub
|
||||
|
||||
|
@ -390,7 +393,7 @@ class Key:
|
|||
return f"Private-key {priv} does not exist"
|
||||
# default to master_sign.pem
|
||||
else:
|
||||
mpriv = self.opts["pki_dir"] + "/" + "master_sign.pem"
|
||||
mpriv = self.pki_dir + "/" + "master_sign.pem"
|
||||
if os.path.isfile(mpriv):
|
||||
priv = mpriv
|
||||
|
||||
|
@ -399,22 +402,17 @@ class Key:
|
|||
log.debug(
|
||||
"Generating new signing key-pair .%s.* in %s",
|
||||
self.opts["master_sign_key_name"],
|
||||
self.opts["pki_dir"],
|
||||
self.pki_dir,
|
||||
)
|
||||
salt.crypt.gen_keys(
|
||||
self.opts["pki_dir"],
|
||||
self.pki_dir,
|
||||
self.opts["master_sign_key_name"],
|
||||
keysize or self.opts["keysize"],
|
||||
self.opts.get("user"),
|
||||
self.passphrase,
|
||||
)
|
||||
|
||||
priv = (
|
||||
self.opts["pki_dir"]
|
||||
+ "/"
|
||||
+ self.opts["master_sign_key_name"]
|
||||
+ ".pem"
|
||||
)
|
||||
priv = self.pki_dir + "/" + self.opts["master_sign_key_name"] + ".pem"
|
||||
else:
|
||||
return "No usable private-key found"
|
||||
|
||||
|
@ -428,7 +426,7 @@ class Key:
|
|||
if not os.path.isdir(signature_path):
|
||||
log.debug("target directory %s does not exist", signature_path)
|
||||
else:
|
||||
signature_path = self.opts["pki_dir"]
|
||||
signature_path = self.pki_dir
|
||||
|
||||
sign_path = signature_path + "/" + self.opts["master_pubkey_signature"]
|
||||
|
||||
|
@ -525,9 +523,9 @@ class Key:
|
|||
Return a dict of local keys
|
||||
"""
|
||||
ret = {"local": []}
|
||||
for fn_ in salt.utils.data.sorted_ignorecase(os.listdir(self.opts["pki_dir"])):
|
||||
for fn_ in salt.utils.data.sorted_ignorecase(os.listdir(self.pki_dir)):
|
||||
if fn_.endswith(".pub") or fn_.endswith(".pem"):
|
||||
path = os.path.join(self.opts["pki_dir"], fn_)
|
||||
path = os.path.join(self.pki_dir, fn_)
|
||||
ret["local"].append(fn_)
|
||||
return ret
|
||||
|
||||
|
@ -600,7 +598,7 @@ class Key:
|
|||
for status, keys in self.name_match(match).items():
|
||||
ret[status] = {}
|
||||
for key in salt.utils.data.sorted_ignorecase(keys):
|
||||
path = os.path.join(self.opts["pki_dir"], status, key)
|
||||
path = os.path.join(self.pki_dir, status, key)
|
||||
with salt.utils.files.fopen(path, "r") as fp_:
|
||||
ret[status][key] = salt.utils.stringutils.to_unicode(fp_.read())
|
||||
return ret
|
||||
|
@ -613,7 +611,7 @@ class Key:
|
|||
for status, keys in self.list_keys().items():
|
||||
ret[status] = {}
|
||||
for key in salt.utils.data.sorted_ignorecase(keys):
|
||||
path = os.path.join(self.opts["pki_dir"], status, key)
|
||||
path = os.path.join(self.pki_dir, status, key)
|
||||
with salt.utils.files.fopen(path, "r") as fp_:
|
||||
ret[status][key] = salt.utils.stringutils.to_unicode(fp_.read())
|
||||
return ret
|
||||
|
@ -639,7 +637,7 @@ class Key:
|
|||
invalid_keys = []
|
||||
for keydir in keydirs:
|
||||
for key in matches.get(keydir, []):
|
||||
key_path = os.path.join(self.opts["pki_dir"], keydir, key)
|
||||
key_path = os.path.join(self.pki_dir, keydir, key)
|
||||
try:
|
||||
salt.crypt.get_rsa_pub_key(key_path)
|
||||
except salt.exceptions.InvalidKeyError:
|
||||
|
@ -649,7 +647,7 @@ class Key:
|
|||
try:
|
||||
shutil.move(
|
||||
key_path,
|
||||
os.path.join(self.opts["pki_dir"], self.ACC, key),
|
||||
os.path.join(self.pki_dir, self.ACC, key),
|
||||
)
|
||||
eload = {"result": True, "act": "accept", "id": key}
|
||||
self.event.fire_event(eload, salt.utils.event.tagify(prefix="key"))
|
||||
|
@ -668,8 +666,8 @@ class Key:
|
|||
for key in keys[self.PEND]:
|
||||
try:
|
||||
shutil.move(
|
||||
os.path.join(self.opts["pki_dir"], self.PEND, key),
|
||||
os.path.join(self.opts["pki_dir"], self.ACC, key),
|
||||
os.path.join(self.pki_dir, self.PEND, key),
|
||||
os.path.join(self.pki_dir, self.ACC, key),
|
||||
)
|
||||
eload = {"result": True, "act": "accept", "id": key}
|
||||
self.event.fire_event(eload, salt.utils.event.tagify(prefix="key"))
|
||||
|
@ -713,7 +711,7 @@ class Key:
|
|||
"master AES key is rotated or auth is revoked "
|
||||
"with 'saltutil.revoke_auth'.".format(key)
|
||||
)
|
||||
os.remove(os.path.join(self.opts["pki_dir"], status, key))
|
||||
os.remove(os.path.join(self.pki_dir, status, key))
|
||||
eload = {"result": True, "act": "delete", "id": key}
|
||||
self.event.fire_event(
|
||||
eload, salt.utils.event.tagify(prefix="key")
|
||||
|
@ -738,7 +736,7 @@ class Key:
|
|||
for status, keys in self.list_keys().items():
|
||||
for key in keys[self.DEN]:
|
||||
try:
|
||||
os.remove(os.path.join(self.opts["pki_dir"], status, key))
|
||||
os.remove(os.path.join(self.pki_dir, status, key))
|
||||
eload = {"result": True, "act": "delete", "id": key}
|
||||
self.event.fire_event(eload, salt.utils.event.tagify(prefix="key"))
|
||||
except OSError:
|
||||
|
@ -753,7 +751,7 @@ class Key:
|
|||
for status, keys in self.list_keys().items():
|
||||
for key in keys:
|
||||
try:
|
||||
os.remove(os.path.join(self.opts["pki_dir"], status, key))
|
||||
os.remove(os.path.join(self.pki_dir, status, key))
|
||||
eload = {"result": True, "act": "delete", "id": key}
|
||||
self.event.fire_event(eload, salt.utils.event.tagify(prefix="key"))
|
||||
except OSError:
|
||||
|
@ -787,8 +785,8 @@ class Key:
|
|||
for key in matches.get(keydir, []):
|
||||
try:
|
||||
shutil.move(
|
||||
os.path.join(self.opts["pki_dir"], keydir, key),
|
||||
os.path.join(self.opts["pki_dir"], self.REJ, key),
|
||||
os.path.join(self.pki_dir, keydir, key),
|
||||
os.path.join(self.pki_dir, self.REJ, key),
|
||||
)
|
||||
eload = {"result": True, "act": "reject", "id": key}
|
||||
self.event.fire_event(eload, salt.utils.event.tagify(prefix="key"))
|
||||
|
@ -809,8 +807,8 @@ class Key:
|
|||
for key in keys[self.PEND]:
|
||||
try:
|
||||
shutil.move(
|
||||
os.path.join(self.opts["pki_dir"], self.PEND, key),
|
||||
os.path.join(self.opts["pki_dir"], self.REJ, key),
|
||||
os.path.join(self.pki_dir, self.PEND, key),
|
||||
os.path.join(self.pki_dir, self.REJ, key),
|
||||
)
|
||||
eload = {"result": True, "act": "reject", "id": key}
|
||||
self.event.fire_event(eload, salt.utils.event.tagify(prefix="key"))
|
||||
|
@ -836,9 +834,9 @@ class Key:
|
|||
ret[status] = {}
|
||||
for key in keys:
|
||||
if status == "local":
|
||||
path = os.path.join(self.opts["pki_dir"], key)
|
||||
path = os.path.join(self.pki_dir, key)
|
||||
else:
|
||||
path = os.path.join(self.opts["pki_dir"], status, key)
|
||||
path = os.path.join(self.pki_dir, status, key)
|
||||
ret[status][key] = salt.utils.crypt.pem_finger(path, sum_type=hash_type)
|
||||
return ret
|
||||
|
||||
|
@ -854,9 +852,9 @@ class Key:
|
|||
ret[status] = {}
|
||||
for key in keys:
|
||||
if status == "local":
|
||||
path = os.path.join(self.opts["pki_dir"], key)
|
||||
path = os.path.join(self.pki_dir, key)
|
||||
else:
|
||||
path = os.path.join(self.opts["pki_dir"], status, key)
|
||||
path = os.path.join(self.pki_dir, status, key)
|
||||
ret[status][key] = salt.utils.crypt.pem_finger(path, sum_type=hash_type)
|
||||
return ret
|
||||
|
||||
|
|
|
@ -289,13 +289,13 @@ class Maintenance(salt.utils.process.SignalHandlingProcess):
|
|||
else:
|
||||
acc = "accepted"
|
||||
|
||||
for fn_ in os.listdir(os.path.join(self.opts["pki_dir"], acc)):
|
||||
for fn_ in os.listdir(os.path.join(self.pki_dir, acc)):
|
||||
if not fn_.startswith("."):
|
||||
keys.append(fn_)
|
||||
log.debug("Writing master key cache")
|
||||
# Write a temporary file securely
|
||||
with salt.utils.atomicfile.atomic_open(
|
||||
os.path.join(self.opts["pki_dir"], acc, ".key_cache"), mode="wb"
|
||||
os.path.join(self.pki_dir, acc, ".key_cache"), mode="wb"
|
||||
) as cache_file:
|
||||
salt.payload.dump(keys, cache_file)
|
||||
|
||||
|
@ -1309,6 +1309,10 @@ class AESFuncs(TransportMethods):
|
|||
)
|
||||
self.__setup_fileserver()
|
||||
self.masterapi = salt.daemons.masterapi.RemoteFuncs(opts)
|
||||
if "cluster_id" in self.opts and self.opts["cluster_id"]:
|
||||
self.pki_dir = self.opts["cluster_pki_dir"]
|
||||
else:
|
||||
self.pki_dir = self.opts.get("pki_dir", "")
|
||||
|
||||
def __setup_fileserver(self):
|
||||
"""
|
||||
|
@ -1341,8 +1345,7 @@ class AESFuncs(TransportMethods):
|
|||
"""
|
||||
if not salt.utils.verify.valid_id(self.opts, id_):
|
||||
return False
|
||||
pub_path = os.path.join(self.opts["pki_dir"], "minions", id_)
|
||||
|
||||
pub_path = os.path.join(self.pki_dir, "minions", id_)
|
||||
try:
|
||||
pub = salt.crypt.get_rsa_pub_key(pub_path)
|
||||
except OSError:
|
||||
|
@ -1764,7 +1767,7 @@ class AESFuncs(TransportMethods):
|
|||
log.trace("Verifying signed event publish from minion")
|
||||
sig = load.pop("sig")
|
||||
this_minion_pubkey = os.path.join(
|
||||
self.opts["pki_dir"], "minions/{}".format(load["id"])
|
||||
self.pki_dir, "minions/{}".format(load["id"])
|
||||
)
|
||||
serialized_load = salt.serializers.msgpack.serialize(load)
|
||||
if not salt.crypt.verify_signature(
|
||||
|
|
|
@ -216,6 +216,10 @@ class CkMinions:
|
|||
self.acc = "minions"
|
||||
else:
|
||||
self.acc = "accepted"
|
||||
if self.opts.get("cluster_id", None) is not None:
|
||||
self.pki_dir = self.opts.get("cluster_pki_dir", "")
|
||||
else:
|
||||
self.pki_dir = self.opts.get("pki_dir", "")
|
||||
|
||||
def _check_nodegroup_minions(self, expr, greedy): # pylint: disable=unused-argument
|
||||
"""
|
||||
|
@ -261,7 +265,7 @@ class CkMinions:
|
|||
Respects cache if configured
|
||||
"""
|
||||
minions = []
|
||||
pki_cache_fn = os.path.join(self.opts["pki_dir"], self.acc, ".key_cache")
|
||||
pki_cache_fn = os.path.join(self.pki_dir, self.acc, ".key_cache")
|
||||
try:
|
||||
os.makedirs(os.path.dirname(pki_cache_fn))
|
||||
except OSError:
|
||||
|
@ -273,7 +277,7 @@ class CkMinions:
|
|||
return salt.payload.load(fn_)
|
||||
else:
|
||||
for fn_ in salt.utils.data.sorted_ignorecase(
|
||||
os.listdir(os.path.join(self.opts["pki_dir"], self.acc))
|
||||
os.listdir(os.path.join(self.pki_dir, self.acc))
|
||||
):
|
||||
if not fn_.startswith("."):
|
||||
minions.append(fn_)
|
||||
|
@ -301,7 +305,7 @@ class CkMinions:
|
|||
if greedy:
|
||||
minions = []
|
||||
for fn_ in salt.utils.data.sorted_ignorecase(
|
||||
os.listdir(os.path.join(self.opts["pki_dir"], self.acc))
|
||||
os.listdir(os.path.join(self.pki_dir, self.acc))
|
||||
):
|
||||
if not fn_.startswith("."):
|
||||
minions.append(fn_)
|
||||
|
@ -447,7 +451,7 @@ class CkMinions:
|
|||
if greedy:
|
||||
mlist = []
|
||||
for fn_ in salt.utils.data.sorted_ignorecase(
|
||||
os.listdir(os.path.join(self.opts["pki_dir"], self.acc))
|
||||
os.listdir(os.path.join(self.pki_dir, self.acc))
|
||||
):
|
||||
if not fn_.startswith("."):
|
||||
mlist.append(fn_)
|
||||
|
@ -677,7 +681,7 @@ class CkMinions:
|
|||
"""
|
||||
mlist = []
|
||||
for fn_ in salt.utils.data.sorted_ignorecase(
|
||||
os.listdir(os.path.join(self.opts["pki_dir"], self.acc))
|
||||
os.listdir(os.path.join(self.pki_dir, self.acc))
|
||||
):
|
||||
if not fn_.startswith("."):
|
||||
mlist.append(fn_)
|
||||
|
|
|
@ -298,15 +298,26 @@ def verify_env(
|
|||
# If acls are enabled, the pki_dir needs to remain readable, this
|
||||
# is still secure because the private keys are still only readable
|
||||
# by the user running the master
|
||||
if dir_ == pki_dir:
|
||||
smode = stat.S_IMODE(mode.st_mode)
|
||||
if smode != 448 and smode != 488:
|
||||
if os.access(dir_, os.W_OK):
|
||||
os.chmod(dir_, 448)
|
||||
else:
|
||||
log.critical(
|
||||
'Unable to securely set the permissions of "%s".', dir_
|
||||
)
|
||||
if isinstance(pki_dir, str):
|
||||
if dir_ == pki_dir:
|
||||
smode = stat.S_IMODE(mode.st_mode)
|
||||
if smode != 448 and smode != 488:
|
||||
if os.access(dir_, os.W_OK):
|
||||
os.chmod(dir_, 448)
|
||||
else:
|
||||
log.critical(
|
||||
'Unable to securely set the permissions of "%s".', dir_
|
||||
)
|
||||
else:
|
||||
if dir_ in pki_dir:
|
||||
smode = stat.S_IMODE(mode.st_mode)
|
||||
if smode != 448 and smode != 488:
|
||||
if os.access(dir_, os.W_OK):
|
||||
os.chmod(dir_, 448)
|
||||
else:
|
||||
log.critical(
|
||||
'Unable to securely set the permissions of "%s".', dir_
|
||||
)
|
||||
|
||||
if skip_extra is False:
|
||||
# Run the extra verification checks
|
||||
|
@ -539,6 +550,10 @@ def valid_id(opts, id_):
|
|||
try:
|
||||
if any(x in id_ for x in ("/", "\\", "\0")):
|
||||
return False
|
||||
if opts.get("cluster_id", None) is not None:
|
||||
pki_dir = opts["cluster_pki_dir"]
|
||||
else:
|
||||
pki_dir = opts["pki_dir"]
|
||||
return bool(clean_path(opts["pki_dir"], id_))
|
||||
except (AttributeError, KeyError, TypeError, UnicodeDecodeError):
|
||||
return False
|
||||
|
|
|
@ -478,23 +478,25 @@ def test_serverside_exception(temp_salt_minion, temp_salt_master):
|
|||
assert ret == "Server-side exception handling payload"
|
||||
|
||||
|
||||
def test_req_server_chan_encrypt_v2(pki_dir):
|
||||
def test_req_server_chan_encrypt_v2(master_opts, pki_dir):
|
||||
loop = tornado.ioloop.IOLoop.current()
|
||||
opts = {
|
||||
"worker_threads": 1,
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"zmq_monitor": False,
|
||||
"mworker_queue_niceness": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("master")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
}
|
||||
server = salt.channel.server.ReqServerChannel.factory(opts)
|
||||
master_opts.update(
|
||||
{
|
||||
"worker_threads": 1,
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"zmq_monitor": False,
|
||||
"mworker_queue_niceness": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("master")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
}
|
||||
)
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
dictkey = "pillar"
|
||||
nonce = "abcdefg"
|
||||
pillar_data = {"pillar1": "meh"}
|
||||
|
@ -511,7 +513,7 @@ def test_req_server_chan_encrypt_v2(pki_dir):
|
|||
else:
|
||||
cipher = PKCS1_OAEP.new(key)
|
||||
aes = cipher.decrypt(ret["key"])
|
||||
pcrypt = salt.crypt.Crypticle(opts, aes)
|
||||
pcrypt = salt.crypt.Crypticle(master_opts, aes)
|
||||
signed_msg = pcrypt.loads(ret[dictkey])
|
||||
|
||||
assert "sig" in signed_msg
|
||||
|
@ -527,23 +529,25 @@ def test_req_server_chan_encrypt_v2(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
def test_req_server_chan_encrypt_v1(pki_dir):
|
||||
def test_req_server_chan_encrypt_v1(master_opts, pki_dir):
|
||||
loop = tornado.ioloop.IOLoop.current()
|
||||
opts = {
|
||||
"worker_threads": 1,
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"zmq_monitor": False,
|
||||
"mworker_queue_niceness": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("master")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
}
|
||||
server = salt.channel.server.ReqServerChannel.factory(opts)
|
||||
master_opts.update(
|
||||
{
|
||||
"worker_threads": 1,
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"zmq_monitor": False,
|
||||
"mworker_queue_niceness": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("master")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
}
|
||||
)
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
dictkey = "pillar"
|
||||
nonce = "abcdefg"
|
||||
pillar_data = {"pillar1": "meh"}
|
||||
|
@ -563,31 +567,33 @@ def test_req_server_chan_encrypt_v1(pki_dir):
|
|||
else:
|
||||
cipher = PKCS1_OAEP.new(key)
|
||||
aes = cipher.decrypt(ret["key"])
|
||||
pcrypt = salt.crypt.Crypticle(opts, aes)
|
||||
pcrypt = salt.crypt.Crypticle(master_opts, aes)
|
||||
data = pcrypt.loads(ret[dictkey])
|
||||
assert data == pillar_data
|
||||
finally:
|
||||
server.close()
|
||||
|
||||
|
||||
def test_req_chan_decode_data_dict_entry_v1(pki_dir):
|
||||
def test_req_chan_decode_data_dict_entry_v1(minion_opts, master_opts, pki_dir):
|
||||
mockloop = MagicMock()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
client = salt.channel.client.ReqChannel.factory(opts, io_loop=mockloop)
|
||||
client = salt.channel.client.ReqChannel.factory(minion_opts, io_loop=mockloop)
|
||||
try:
|
||||
dictkey = "pillar"
|
||||
target = "minion"
|
||||
|
@ -607,24 +613,26 @@ def test_req_chan_decode_data_dict_entry_v1(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_decode_data_dict_entry_v2(pki_dir):
|
||||
async def test_req_chan_decode_data_dict_entry_v2(minion_opts, master_opts, pki_dir):
|
||||
mockloop = MagicMock()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=mockloop)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=mockloop)
|
||||
|
||||
dictkey = "pillar"
|
||||
target = "minion"
|
||||
|
@ -632,7 +640,7 @@ async def test_req_chan_decode_data_dict_entry_v2(pki_dir):
|
|||
|
||||
# Mock auth and message client.
|
||||
auth = client.auth
|
||||
auth._crypticle = salt.crypt.Crypticle(opts, AES_KEY)
|
||||
auth._crypticle = salt.crypt.Crypticle(minion_opts, AES_KEY)
|
||||
client.auth = MagicMock()
|
||||
client.auth.mpub = auth.mpub
|
||||
client.auth.authenticated = True
|
||||
|
@ -679,24 +687,28 @@ async def test_req_chan_decode_data_dict_entry_v2(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_decode_data_dict_entry_v2_bad_nonce(pki_dir):
|
||||
async def test_req_chan_decode_data_dict_entry_v2_bad_nonce(
|
||||
minion_opts, master_opts, pki_dir
|
||||
):
|
||||
mockloop = MagicMock()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=mockloop)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=mockloop)
|
||||
|
||||
dictkey = "pillar"
|
||||
badnonce = "abcdefg"
|
||||
|
@ -705,7 +717,7 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_nonce(pki_dir):
|
|||
|
||||
# Mock auth and message client.
|
||||
auth = client.auth
|
||||
auth._crypticle = salt.crypt.Crypticle(opts, AES_KEY)
|
||||
auth._crypticle = salt.crypt.Crypticle(minion_opts, AES_KEY)
|
||||
client.auth = MagicMock()
|
||||
client.auth.mpub = auth.mpub
|
||||
client.auth.authenticated = True
|
||||
|
@ -751,24 +763,28 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_nonce(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_decode_data_dict_entry_v2_bad_signature(pki_dir):
|
||||
async def test_req_chan_decode_data_dict_entry_v2_bad_signature(
|
||||
minion_opts, master_opts, pki_dir
|
||||
):
|
||||
mockloop = MagicMock()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=mockloop)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=mockloop)
|
||||
|
||||
dictkey = "pillar"
|
||||
badnonce = "abcdefg"
|
||||
|
@ -777,7 +793,7 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_signature(pki_dir):
|
|||
|
||||
# Mock auth and message client.
|
||||
auth = client.auth
|
||||
auth._crypticle = salt.crypt.Crypticle(opts, AES_KEY)
|
||||
auth._crypticle = salt.crypt.Crypticle(minion_opts, AES_KEY)
|
||||
client.auth = MagicMock()
|
||||
client.auth.mpub = auth.mpub
|
||||
client.auth.authenticated = True
|
||||
|
@ -839,24 +855,28 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_signature(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_decode_data_dict_entry_v2_bad_key(pki_dir):
|
||||
async def test_req_chan_decode_data_dict_entry_v2_bad_key(
|
||||
minion_opts, master_opts, pki_dir
|
||||
):
|
||||
mockloop = MagicMock()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=mockloop)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=mockloop)
|
||||
|
||||
dictkey = "pillar"
|
||||
badnonce = "abcdefg"
|
||||
|
@ -865,7 +885,7 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_key(pki_dir):
|
|||
|
||||
# Mock auth and message client.
|
||||
auth = client.auth
|
||||
auth._crypticle = salt.crypt.Crypticle(opts, AES_KEY)
|
||||
auth._crypticle = salt.crypt.Crypticle(minion_opts, AES_KEY)
|
||||
client.auth = MagicMock()
|
||||
client.auth.mpub = auth.mpub
|
||||
client.auth.authenticated = True
|
||||
|
@ -895,7 +915,7 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_key(pki_dir):
|
|||
|
||||
# Now encrypt with a different key
|
||||
key = salt.crypt.Crypticle.generate_key_string()
|
||||
pcrypt = salt.crypt.Crypticle(opts, key)
|
||||
pcrypt = salt.crypt.Crypticle(minion_opts, key)
|
||||
pubfn = os.path.join(master_opts["pki_dir"], "minions", "minion")
|
||||
pub = salt.crypt.get_rsa_pub_key(pubfn)
|
||||
ret[dictkey] = pcrypt.dumps(signed_msg)
|
||||
|
@ -934,25 +954,27 @@ async def test_req_chan_decode_data_dict_entry_v2_bad_key(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_serv_auth_v1(pki_dir):
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"master_sign_pubkey": False,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
}
|
||||
async def test_req_serv_auth_v1(minion_opts, master_opts, pki_dir):
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"master_sign_pubkey": False,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -960,7 +982,7 @@ async def test_req_serv_auth_v1(pki_dir):
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
|
@ -990,25 +1012,27 @@ async def test_req_serv_auth_v1(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_serv_auth_v2(pki_dir):
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"master_sign_pubkey": False,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
}
|
||||
async def test_req_serv_auth_v2(minion_opts, master_opts, pki_dir):
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"master_sign_pubkey": False,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -1016,7 +1040,7 @@ async def test_req_serv_auth_v2(pki_dir):
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
|
@ -1048,26 +1072,28 @@ async def test_req_serv_auth_v2(pki_dir):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_auth_v2(pki_dir, io_loop):
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
async def test_req_chan_auth_v2(minion_opts, master_opts, pki_dir, io_loop):
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -1075,15 +1101,15 @@ async def test_req_chan_auth_v2(pki_dir, io_loop):
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts["master_sign_pubkey"] = False
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
server.master_key = salt.crypt.MasterKeys(server.opts)
|
||||
opts["verify_master_pubkey_sign"] = False
|
||||
opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=io_loop)
|
||||
minion_opts["verify_master_pubkey_sign"] = False
|
||||
minion_opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=io_loop)
|
||||
signin_payload = client.auth.minion_sign_in_payload()
|
||||
pload = client._package_load(signin_payload)
|
||||
try:
|
||||
|
@ -1101,26 +1127,30 @@ async def test_req_chan_auth_v2(pki_dir, io_loop):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_auth_v2_with_master_signing(pki_dir, io_loop):
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
async def test_req_chan_auth_v2_with_master_signing(
|
||||
minion_opts, master_opts, pki_dir, io_loop
|
||||
):
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -1128,7 +1158,7 @@ async def test_req_chan_auth_v2_with_master_signing(pki_dir, io_loop):
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts["master_sign_pubkey"] = True
|
||||
master_opts["master_use_pubkey_signature"] = False
|
||||
master_opts["signing_key_pass"] = True
|
||||
|
@ -1137,17 +1167,17 @@ async def test_req_chan_auth_v2_with_master_signing(pki_dir, io_loop):
|
|||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
server.master_key = salt.crypt.MasterKeys(server.opts)
|
||||
opts["verify_master_pubkey_sign"] = True
|
||||
opts["always_verify_signature"] = True
|
||||
opts["master_sign_key_name"] = "master_sign"
|
||||
opts["master"] = "master"
|
||||
minion_opts["verify_master_pubkey_sign"] = True
|
||||
minion_opts["always_verify_signature"] = True
|
||||
minion_opts["master_sign_key_name"] = "master_sign"
|
||||
minion_opts["master"] = "master"
|
||||
|
||||
assert (
|
||||
pki_dir.joinpath("minion", "minion_master.pub").read_text()
|
||||
== pki_dir.joinpath("master", "master.pub").read_text()
|
||||
)
|
||||
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=io_loop)
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=io_loop)
|
||||
signin_payload = client.auth.minion_sign_in_payload()
|
||||
pload = client._package_load(signin_payload)
|
||||
assert "version" in pload
|
||||
|
@ -1196,28 +1226,32 @@ async def test_req_chan_auth_v2_with_master_signing(pki_dir, io_loop):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_auth_v2_new_minion_with_master_pub(pki_dir, io_loop):
|
||||
async def test_req_chan_auth_v2_new_minion_with_master_pub(
|
||||
minion_opts, master_opts, pki_dir, io_loop
|
||||
):
|
||||
|
||||
pki_dir.joinpath("master", "minions", "minion").unlink()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -1225,15 +1259,15 @@ async def test_req_chan_auth_v2_new_minion_with_master_pub(pki_dir, io_loop):
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts["master_sign_pubkey"] = False
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
server.master_key = salt.crypt.MasterKeys(server.opts)
|
||||
opts["verify_master_pubkey_sign"] = False
|
||||
opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=io_loop)
|
||||
minion_opts["verify_master_pubkey_sign"] = False
|
||||
minion_opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=io_loop)
|
||||
signin_payload = client.auth.minion_sign_in_payload()
|
||||
pload = client._package_load(signin_payload)
|
||||
try:
|
||||
|
@ -1249,7 +1283,9 @@ async def test_req_chan_auth_v2_new_minion_with_master_pub(pki_dir, io_loop):
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_auth_v2_new_minion_with_master_pub_bad_sig(pki_dir, io_loop):
|
||||
async def test_req_chan_auth_v2_new_minion_with_master_pub_bad_sig(
|
||||
minion_opts, master_opts, pki_dir, io_loop
|
||||
):
|
||||
|
||||
pki_dir.joinpath("master", "minions", "minion").unlink()
|
||||
|
||||
|
@ -1261,25 +1297,27 @@ async def test_req_chan_auth_v2_new_minion_with_master_pub_bad_sig(pki_dir, io_l
|
|||
mapub.unlink()
|
||||
mapub.write_text(MASTER2_PUB_KEY.strip())
|
||||
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -1287,15 +1325,15 @@ async def test_req_chan_auth_v2_new_minion_with_master_pub_bad_sig(pki_dir, io_l
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts["master_sign_pubkey"] = False
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
server.master_key = salt.crypt.MasterKeys(server.opts)
|
||||
opts["verify_master_pubkey_sign"] = False
|
||||
opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=io_loop)
|
||||
minion_opts["verify_master_pubkey_sign"] = False
|
||||
minion_opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=io_loop)
|
||||
signin_payload = client.auth.minion_sign_in_payload()
|
||||
pload = client._package_load(signin_payload)
|
||||
try:
|
||||
|
@ -1311,29 +1349,33 @@ async def test_req_chan_auth_v2_new_minion_with_master_pub_bad_sig(pki_dir, io_l
|
|||
server.close()
|
||||
|
||||
|
||||
async def test_req_chan_auth_v2_new_minion_without_master_pub(pki_dir, io_loop):
|
||||
async def test_req_chan_auth_v2_new_minion_without_master_pub(
|
||||
minion_opts, master_opts, pki_dir, io_loop
|
||||
):
|
||||
|
||||
pki_dir.joinpath("master", "minions", "minion").unlink()
|
||||
pki_dir.joinpath("minion", "minion_master.pub").unlink()
|
||||
opts = {
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
minion_opts.update(
|
||||
{
|
||||
"master_uri": "tcp://127.0.0.1:4506",
|
||||
"interface": "127.0.0.1",
|
||||
"ret_port": 4506,
|
||||
"ipv6": False,
|
||||
"sock_dir": ".",
|
||||
"pki_dir": str(pki_dir.joinpath("minion")),
|
||||
"id": "minion",
|
||||
"__role": "minion",
|
||||
"keysize": 4096,
|
||||
"max_minions": 0,
|
||||
"auto_accept": False,
|
||||
"open_mode": False,
|
||||
"key_pass": None,
|
||||
"publish_port": 4505,
|
||||
"auth_mode": 1,
|
||||
"acceptance_wait_time": 3,
|
||||
"acceptance_wait_time_max": 3,
|
||||
}
|
||||
)
|
||||
SMaster.secrets["aes"] = {
|
||||
"secret": multiprocessing.Array(
|
||||
ctypes.c_char,
|
||||
|
@ -1341,15 +1383,15 @@ async def test_req_chan_auth_v2_new_minion_without_master_pub(pki_dir, io_loop):
|
|||
),
|
||||
"reload": salt.crypt.Crypticle.generate_key_string,
|
||||
}
|
||||
master_opts = dict(opts, pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts.update(pki_dir=str(pki_dir.joinpath("master")))
|
||||
master_opts["master_sign_pubkey"] = False
|
||||
server = salt.channel.server.ReqServerChannel.factory(master_opts)
|
||||
server.auto_key = salt.daemons.masterapi.AutoKey(server.opts)
|
||||
server.cache_cli = False
|
||||
server.master_key = salt.crypt.MasterKeys(server.opts)
|
||||
opts["verify_master_pubkey_sign"] = False
|
||||
opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(opts, io_loop=io_loop)
|
||||
minion_opts["verify_master_pubkey_sign"] = False
|
||||
minion_opts["always_verify_signature"] = False
|
||||
client = salt.channel.client.AsyncReqChannel.factory(minion_opts, io_loop=io_loop)
|
||||
signin_payload = client.auth.minion_sign_in_payload()
|
||||
pload = client._package_load(signin_payload)
|
||||
try:
|
||||
|
|
|
@ -187,3 +187,45 @@ def test_dropfile_contents(tmp_path, master_opts):
|
|||
salt.crypt.dropfile(str(tmp_path), master_opts["user"], master_id=master_opts["id"])
|
||||
with salt.utils.files.fopen(str(tmp_path / ".dfn"), "r") as fp:
|
||||
assert master_opts["id"] == fp.read()
|
||||
|
||||
|
||||
def test_master_keys_without_cluster_id(tmp_path, master_opts):
|
||||
master_opts["pki_dir"] = str(tmp_path)
|
||||
assert master_opts["cluster_id"] is None
|
||||
assert master_opts["cluster_pki_dir"] is None
|
||||
mkeys = salt.crypt.MasterKeys(master_opts)
|
||||
expected_master_pub = str(tmp_path / "master.pub")
|
||||
expected_master_rsa = str(tmp_path / "master.pem")
|
||||
assert expected_master_pub == mkeys.master_pub_path
|
||||
assert expected_master_rsa == mkeys.master_rsa_path
|
||||
assert mkeys.cluster_pub_path is None
|
||||
assert mkeys.cluster_rsa_path is None
|
||||
assert mkeys.pub_path == expected_master_pub
|
||||
assert mkeys.rsa_path == expected_master_rsa
|
||||
assert mkeys.key == mkeys.master_key
|
||||
|
||||
|
||||
def test_master_keys_with_cluster_id(tmp_path, master_opts):
|
||||
master_pki_path = tmp_path / "master_pki"
|
||||
cluster_pki_path = tmp_path / "cluster_pki"
|
||||
# The paths need to exist
|
||||
master_pki_path.mkdir()
|
||||
cluster_pki_path.mkdir()
|
||||
|
||||
master_opts["pki_dir"] = str(master_pki_path)
|
||||
master_opts["cluster_id"] = "cluster1"
|
||||
master_opts["cluster_pki_dir"] = str(cluster_pki_path)
|
||||
|
||||
mkeys = salt.crypt.MasterKeys(master_opts)
|
||||
|
||||
expected_master_pub = str(master_pki_path / "master.pub")
|
||||
expected_master_rsa = str(master_pki_path / "master.pem")
|
||||
expected_cluster_pub = str(cluster_pki_path / "cluster.pub")
|
||||
expected_cluster_rsa = str(cluster_pki_path / "cluster.pem")
|
||||
assert expected_master_pub == mkeys.master_pub_path
|
||||
assert expected_master_rsa == mkeys.master_rsa_path
|
||||
assert expected_cluster_pub == mkeys.cluster_pub_path
|
||||
assert expected_cluster_rsa == mkeys.cluster_rsa_path
|
||||
assert mkeys.pub_path == expected_cluster_pub
|
||||
assert mkeys.rsa_path == expected_cluster_rsa
|
||||
assert mkeys.key == mkeys.cluster_key
|
||||
|
|
Loading…
Add table
Reference in a new issue