File: //proc/self/root/usr/share/l.v.e-manager/utils/libsupport.py
# coding:utf-8
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
import re
import subprocess
"""Utilities for building custom fields and generating doctor key.
All legacy Zendesk ticket creation code has been removed. New flow expects
the frontend to request custom fields via `cloudlinux-support` command with
method 'custom-fields'.
"""
# Identifiers for custom fields in API
_PRODUCT_ID = 33267569
_DOCTOR_ID = 43297669
def build_custom_fields_from_send_params(params):
"""Build custom fields array based on existing 'send' params.
- Always adds PRODUCT field with value 'cloudlinux'
- Adds CLN and AGREEMENT when present in params
- If clDoctor == 'true', runs doctor and adds DOCTOR_ID field
Returns: list of dicts with 'id' and 'value'
"""
fields = [{
'id': _PRODUCT_ID,
'value': 'cloudlinux'
}]
if params.get('runDoctor') == 'true':
try:
doctor_key = _get_doctor_key()
if doctor_key:
fields.append({'id': _DOCTOR_ID, 'value': doctor_key})
except Exception:
# Silently skip doctor field if generation failed
pass
return fields
#: Locally-installed cldoctor binary. Must be a root-owned executable
#: dropped by the cldoctor package — NOT a script fetched from the network
#: at run time. Piping `curl ... | bash` here turns any successful tamper
#: with the response body (origin compromise, CA mis-issuance, on-path
#: attacker with a forged cert) into RCE in this backend process, so the
#: doctor key generator is allowed to run only when the trusted local
#: binary is present.
_CLDOCTOR_BIN = '/usr/sbin/cldoctor'
def _get_doctor_key():
import os
if not os.path.isfile(_CLDOCTOR_BIN) or not os.access(_CLDOCTOR_BIN, os.X_OK):
raise RuntimeError(
'cldoctor binary is not installed at %s; refusing to fetch and '
'execute a remote shell script for the doctor key.' % _CLDOCTOR_BIN
)
response = subprocess.check_output(
[_CLDOCTOR_BIN], stderr=subprocess.STDOUT, text=True,
)
result = re.search('Key: ([^\n]+)\n', response)
if not result:
raise RuntimeError('cldoctor output did not include a Key: line')
return result.group(1)