176 lines
3.6 KiB
Python
Executable File
176 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import socket
|
|
import sys
|
|
|
|
sys.path.insert(0, "daemon")
|
|
|
|
import server
|
|
from registry import RegistryError
|
|
|
|
|
|
class FakeRegistry:
|
|
def __init__(self):
|
|
self.resources = {
|
|
"postgresql-ha": object(),
|
|
}
|
|
self.executions = []
|
|
|
|
def execute(self, resource, action):
|
|
self.executions.append((resource, action))
|
|
|
|
return {
|
|
"ok": True,
|
|
"resource": resource,
|
|
"plugin": "postgresql",
|
|
"action": action,
|
|
"result": {"accepted": True},
|
|
}
|
|
|
|
|
|
def require(condition, message):
|
|
if not condition:
|
|
raise SystemExit("FAIL: " + message)
|
|
|
|
|
|
def require_registry_error(callback, message):
|
|
try:
|
|
callback()
|
|
except RegistryError:
|
|
return
|
|
|
|
raise SystemExit("FAIL: " + message)
|
|
|
|
|
|
print("===== SO_PEERCRED AUTHORIZATION =====")
|
|
|
|
require_registry_error(
|
|
lambda: server.load_pacemaker_peer_authorization({}),
|
|
"missing peer configuration was accepted",
|
|
)
|
|
print("missing_configuration rejected")
|
|
|
|
require_registry_error(
|
|
lambda: server.load_pacemaker_peer_authorization({
|
|
"PACEMAKER_PEER_UID": "invalid",
|
|
"PACEMAKER_PEER_GID": "65534",
|
|
}),
|
|
"invalid peer configuration was accepted",
|
|
)
|
|
print("invalid_configuration rejected")
|
|
|
|
peer_uid, peer_gid = (
|
|
server.load_pacemaker_peer_authorization({
|
|
"PACEMAKER_PEER_UID": "65534",
|
|
"PACEMAKER_PEER_GID": "65534",
|
|
})
|
|
)
|
|
|
|
require(
|
|
(peer_uid, peer_gid) == (65534, 65534),
|
|
"valid peer configuration was not loaded",
|
|
)
|
|
print("valid_configuration accepted")
|
|
|
|
left, right = socket.socketpair()
|
|
|
|
try:
|
|
observed = server.get_peer_credentials(left)
|
|
finally:
|
|
left.close()
|
|
right.close()
|
|
|
|
require(
|
|
observed["uid"] == os.geteuid(),
|
|
"SO_PEERCRED UID parsing is incorrect",
|
|
)
|
|
require(
|
|
observed["gid"] == os.getegid(),
|
|
"SO_PEERCRED GID parsing is incorrect",
|
|
)
|
|
require(
|
|
isinstance(observed["pid"], int),
|
|
"SO_PEERCRED PID parsing is incorrect",
|
|
)
|
|
print("kernel_credentials parsed")
|
|
|
|
registry = FakeRegistry()
|
|
|
|
server.registry = registry
|
|
server.pacemaker_resource_id = "postgresql-ha"
|
|
server.pacemaker_peer_uid = peer_uid
|
|
server.pacemaker_peer_gid = peer_gid
|
|
|
|
request = {
|
|
"protocol_version": 1,
|
|
"resource": "postgresql-ha",
|
|
"action": "monitor",
|
|
}
|
|
|
|
response = server.handle_request(
|
|
request,
|
|
{
|
|
"pid": 0,
|
|
"uid": 65534,
|
|
"gid": 65534,
|
|
},
|
|
)
|
|
|
|
require(
|
|
response["ok"] is True,
|
|
"authorized root peer was rejected",
|
|
)
|
|
require(
|
|
registry.executions
|
|
== [("postgresql-ha", "monitor")],
|
|
"authorized request did not execute exactly once",
|
|
)
|
|
print("authorized_root_peer executed")
|
|
|
|
response = server.handle_request(
|
|
request,
|
|
{
|
|
"pid": os.getpid(),
|
|
"uid": 1000,
|
|
"gid": 1000,
|
|
},
|
|
)
|
|
|
|
require(
|
|
response["ok"] is False,
|
|
"David peer was authorized",
|
|
)
|
|
require(
|
|
response["error_code"]
|
|
== "peer_credential_mismatch",
|
|
"David rejection has the wrong classification",
|
|
)
|
|
require(
|
|
registry.executions
|
|
== [("postgresql-ha", "monitor")],
|
|
"unauthorized request reached the registry",
|
|
)
|
|
print("david_peer rejected")
|
|
|
|
response = server.handle_request(request)
|
|
|
|
require(
|
|
response["ok"] is False,
|
|
"credential-free request was authorized",
|
|
)
|
|
require(
|
|
response["error_code"]
|
|
== "peer_credentials_unavailable",
|
|
"missing credentials have the wrong classification",
|
|
)
|
|
require(
|
|
registry.executions
|
|
== [("postgresql-ha", "monitor")],
|
|
"credential-free request reached the registry",
|
|
)
|
|
print("missing_credentials rejected")
|
|
|
|
print()
|
|
print("PEER_AUTHORIZATION_TEST_PASS=1")
|