def handleList(self, confInfo): user, app = self.user_app() # reload the conf before reading it try: entity.refreshEntities( self.endpoint, namespace=app, owner=user, sessionKey=self.getSessionKey(), ) except Exception as exc: RH_Err.ctl( 1023, msgx=exc, logLevel=logging.INFO, shouldPrint=False, shouldRaise=False, ) if self.callerArgs.id is None: ents = self.all() for name, ent in list(ents.items()): makeConfItem(name, ent, confInfo, user=user, app=app) else: try: ent = self.get(self.callerArgs.id) makeConfItem(self.callerArgs.id, ent, confInfo, user=user, app=app) except ResourceNotFound as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def user_caps(mgmt_uri, session_key): """ Get capabilities of sessioned Splunk user. :param mgmt_uri: :param session_key: :return: """ url = mgmt_uri.strip('/') + '/services/authentication/current-context' resp, cont = splunkd_request(url, session_key, method='GET', data={'output_mode': 'json'}, retry=3 ) if resp is None: RH_Err.ctl(500, logLevel=logging.ERROR, msgx='Fail to get capabilities of sessioned user') elif resp.status not in (200, '200'): RH_Err.ctl(resp.status, logLevel=logging.ERROR, msgx=cont ) cont = json.loads(cont) caps = cont['entry'][0]['content']['capabilities'] return set(caps)
def check_name(self): """ Check if the object name is valid while creating. :return: """ if (self.requestedAction != admin.ACTION_CREATE or self.callerArgs.id is None): return # not allow to create object with name starting with '_' if self.callerArgs.id.startswith('_'): RH_Err.ctl( 400, msgx='It is not allowed to create object ' 'with name starting with "_"', logLevel=logging.INFO, ) # not allowed name if self.callerArgs.id in self.NOT_ALLOWED_NAME: RH_Err.ctl( 400, msgx='It is not allowed to create object with name "%s"' '' % self.callerArgs.id, logLevel=logging.INFO, )
def setModel(self, name): """Get data model for specified object. """ # get model for object if name not in self.modelMap: RH_Err.ctl(404, msgx='object={name}'.format( name=name, handler=self.__class__.__name__)) self.model = self.modelMap[name] # load attributes from model obj = self.model() attrs = { attr: getattr(obj, attr, None) for attr in dir(obj) if not attr.startswith('__') and attr not in ( 'endpoint', 'rest_prefix', 'cap4endpoint', 'cap4get_cred') } self.__dict__.update(attrs) # credential fields self.encryptedArgs = set([(self.keyMap.get(arg) or arg) for arg in self.encryptedArgs]) user, app = self.user_app() self._cred_mgmt = NessusCredMgmt( sessionKey=self.getSessionKey(), user=user, app=app, endpoint=self.endpoint, encryptedArgs=self.encryptedArgs, ) return
def handleList(self, conf_info): logger.info("start listing google subscriptions") for required in self.valid_params: if not self.callerArgs or not self.callerArgs.get(required): logger.error('Missing "%s"', required) raise Exception('Missing "{}"'.format(required)) stanza_name = self.callerArgs[ggc.google_credentials_name][0] config = gconf.get_google_settings(scc.getMgmtUri(), self.getSessionKey(), cred_name=stanza_name) project = self.callerArgs[ggc.google_project][0] config.update({ "service_name": "storage", "version": "v1", "scopes": ["https://www.googleapis.com/auth/cloud-platform.read-only"] }) storage = create_google_client(config) buckets = storage.buckets() bucket_names = list() request = buckets.list(project=project) while request: try: response = request.execute() except googleapiclient.errors.HttpError, exc: RH_Err.ctl(400, exc) names = [item.get('name') for item in response.get('items')] bucket_names.extend(names) request = buckets.list_next(request, response)
def _reload(self, confInfo): path = "%s/_reload" % self.endpoint response, _ = rest.simpleRequest( path, sessionKey=self.getSessionKey(), method="POST" ) if response.status != 200: exc = RESTException(response.status, response.messages) RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def decode(self, name, ent): """Decode data before return it. :param name: :param ent: :return: """ # Automatically encrypt credential information # It is for manually edited *.conf file ent = self._auto_encrypt(name, ent) # decrypt if self.callerArgs.data.get('--get-clear-credential--') == ['1']: try: ent = self._cred_mgmt.decrypt(self._makeStanzaName(name), ent) except ResourceNotFound: RH_Err.ctl(1021, msgx='endpoint=%s, item=%s' % (self.endpoint, name), shouldPrint=False, shouldRaise=False) else: ent = { key: val for key, val in ent.iteritems() if key not in self.encryptedArgs } # Adverse Key Mapping ent = {k: v for k, v in ent.iteritems()} keyMapAdv = {v: k for k, v in self.keyMap.items()} ent_new = {keyMapAdv[k]: vs for k, vs in ent.items() if k in keyMapAdv} ent.update(ent_new) # Adverse Value Mapping valMapAdv = { k: {y: x for x, y in m.items()} for k, m in self.valMap.items() } ent = { k: (([(valMapAdv[k].get(v) or v) for v in vs] if isinstance(vs, list) else (valMapAdv[k].get(vs) or vs)) if k in valMapAdv else vs) for k, vs in ent.items() } # normalize ent = self.normalize(ent) # filter undesired arguments & handle none value return { k: ((str(v).lower() if isinstance(v, bool) else v) if (v is not None and str(v).strip()) else '') for k, v in ent.iteritems() if k not in self.transientArgs and ( self.allowExtra or k in self.requiredArgs or k in self.optionalArgs or k in self.outputExtraFields) }
def checkCustomAction(self, action, cap_name): if self.customAction != action: return # cap = getattr(self, cap_name, '') # if not cap: # RH_Err.ctl(1101, # msgx='action=%s' % action, # shouldPrint=True) if self.callerArgs.id is None: RH_Err.ctl(1101, msgx='None object specified')
def create(self, name, **params): user, app = self.user_app() new = entity.Entity(self.endpoint, "_new", namespace=app, owner=user) try: new["name"] = name for arg, val in list(params.items()): new[arg] = val entity.setEntity(new, sessionKey=self.getSessionKey()) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def handleEdit(self, confInfo): try: self.get(self.callerArgs.id) except Exception as exc: RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO) try: args = self.encode(self.callerArgs.data, setDefault=False) self.update(self.callerArgs.id, **args) self.handleList(confInfo) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def check_entries(self, endpoint, entries): for ent in entries: name, ent = ent['name'], ent['content'] for field in endpoint['fields']: val = ent.get(field) if isinstance(val, string_types): val = [val] if self.callerArgs.id in val: RH_Err.ctl( 400, 'It is still used in %s "%s"' '' % (endpoint['description'], name), )
def handleRemove(self, confInfo): try: for ep in self._depended_endpoints: url = self.make_endpoint_url(ep.get('endpoint')) resp, cont = splunkd_request(url, self.getSessionKey(), data={'output_mode': 'json'}) if resp.status not in (200, '200'): raise Exception(cont) res = json.loads(cont) self.check_entries(ep, res['entry']) except Exception, exc: RH_Err.ctl(1105, exc)
def update(self, name, **params): user, app = self.user_app() try: ent = entity.getEntity(self.endpoint, name, namespace=app, owner=user, sessionKey=self.getSessionKey()) for arg, val in params.items(): ent[arg] = val entity.setEntity(ent, sessionKey=self.getSessionKey()) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def validate(self, args): """Validate request arguments.""" for k, vs in list(args.items()): if k not in self.validators or not vs: continue if not isinstance(vs, list): vs = [vs] for v in vs: if not self.validators[k].validate(v, args): RH_Err.ctl( 1100, msgx=(f"{self.validators[k].msg} - field={k}"), logLevel=logging.INFO, ) return args
def handleCustom(self, confInfo, **params): if self.customAction in ["acl"]: return self.handleACL(confInfo) if self.customAction == "disable": self.handleDisableAction(confInfo, "1") elif self.customAction == "enable": self.handleDisableAction(confInfo, "0") elif self.customAction == "_reload": self._reload(confInfo) elif self.customAction == "move": self.move(confInfo, **params) elif self.customAction == "_sync": self.handleSyncAction(confInfo, **params) else: RH_Err.ctl(1101, "action=%s" % self.customAction, logLevel=logging.INFO)
def validate(self, data): """Validate request arguments. """ for f, vs in data.iteritems(): if f not in self.validators or not vs: continue vs = [vs] if not isinstance(vs, list) else vs for v in vs: if not self.validators[f].validate(v, data): RH_Err.ctl( 1100, msgx=('field="{f}" - {msg}' ''.format(msg=self.validators[f].msg, f=f)), logLevel=logging.DEBUG, ) return data
def handleCreate(self, confInfo): try: # nosemgrep: gitlab.bandit.B110 self.get(self.callerArgs.id) except Exception: pass else: RH_Err.ctl( 409, msgx=("object=%s" % self.callerArgs.id), logLevel=logging.INFO ) try: args = self.encode(self.callerArgs.data) self.create(self.callerArgs.id, **args) self.handleList(confInfo) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def handleCreate(self, confInfo): try: self.get(self.callerArgs.id) except: pass else: RH_Err.ctl(409, msgx=('object=%s' % self.callerArgs.id), logLevel=logging.INFO) try: args = self.encode(self.callerArgs.data) self.create(self.callerArgs.id, **args) self.handleList(confInfo) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def handleList(self, confInfo): user, app = self.user_app() # reload the conf before reading it try: entity.refreshEntities(self.endpoint, namespace=app, owner=user, sessionKey=self.getSessionKey()) except Exception, exc: RH_Err.ctl( 1023, msgx=exc, logLevel=logging.INFO, shouldPrint=False, shouldRaise=False, )
def move(self, confInfo, **params): user, app = self.user_app() args = self.getCallerArgs() if hasattr(self, "encode"): args = self.encode(args) postArgs = {"app": args["app"], "user": args["user"]} path = entity.buildEndpoint( self.endpoint, entityName=self.callerArgs.id, namespace=app, owner=user ) path += "/move" response, _ = rest.simpleRequest( path, sessionKey=self.getSessionKey(), method="POST", postargs=postArgs ) if response.status != 200: exc = RESTException(response.status, response.messages) RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def get_entities(endpoint, session_key, user, app, get_args): url = rest.makeSplunkdUri() + "servicesNS/" + user + "/" + app + "/" + endpoint try: response, content = rest.simpleRequest( url, sessionKey=session_key, method="GET", getargs=get_args, raiseAllErrors=True, ) res = json.loads(content) if "entry" in res: return {entry["name"]: entry["content"] for entry in res["entry"]} else: return {} except Exception as exc: RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO) return
def handleCustom(self, confInfo, **params): if self.customAction in ['acl']: return self.handleACL(confInfo) if self.customAction == 'disable': self.handleDisableAction(confInfo, '1') elif self.customAction == 'enable': self.handleDisableAction(confInfo, '0') elif self.customAction == "_reload": self._reload(confInfo) elif self.customAction == "move": self.move(confInfo, **params) elif self.customAction == '_sync': self.handleSyncAction(confInfo, **params) else: RH_Err.ctl(1101, 'action=%s' % self.customAction, logLevel=logging.INFO)
def get_entities(endpoint, session_key, user, app, get_args): url = rest.makeSplunkdUri() + 'servicesNS/' + user + '/' + app + \ '/' + endpoint try: response, content = rest.simpleRequest( url, sessionKey=session_key, method='GET', getargs=get_args, raiseAllErrors=True, ) res = json.loads(content) if 'entry' in res: return {entry['name']: entry['content'] for entry in res['entry']} else: return {} except Exception as exc: RH_Err.ctl(-1, msgx=exc, logLevel=logging.INFO) return
def check_caps(self): current_caps = user_caps(rest.makeSplunkdUri(), self.getSessionKey()) cap4endpoint = (self.rest_prefix + "_" + self.cap4endpoint if self.cap4endpoint else "") if cap4endpoint and cap4endpoint not in current_caps: RH_Err.ctl(403, msgx="capability=" + cap4endpoint, logLevel=logging.INFO) if 0 < len(self.customAction): self.customActionCap = cap4endpoint cap4get_cred = (self.rest_prefix + "_" + self.cap4get_cred if self.cap4get_cred else "") if ("--get-clear-credential--" in self.callerArgs.data and cap4get_cred and cap4get_cred not in current_caps): RH_Err.ctl(403, msgx="capability=" + cap4get_cred, logLevel=logging.INFO)
def user_caps(mgmt_uri, session_key): """ Get capabilities of sessioned Splunk user. :param mgmt_uri: :param session_key: :return: """ url = mgmt_uri + "/services/authentication/current-context" resp = splunkd_request( url, session_key, method="GET", data={"output_mode": "json"}, retry=3 ) if resp is None: RH_Err.ctl(500, logging.ERROR, "Fail to get capabilities of sessioned user") elif resp.status_code != 200: RH_Err.ctl(resp.status_code, logging.ERROR, resp.text) cont = resp.json() caps = cont["entry"][0]["content"]["capabilities"] return set(caps)
def check_caps(self): current_caps = ucc_rh_util.user_caps( rest.makeSplunkdUri(), self.getSessionKey(), ) cap4endpoint = self.rest_prefix + '_' + self.cap4endpoint \ if self.cap4endpoint else '' if cap4endpoint and cap4endpoint not in current_caps: RH_Err.ctl(403, msgx='capability=' + cap4endpoint, logLevel=logging.INFO) if 0 < len(self.customAction): self.customActionCap = cap4endpoint cap4get_cred = self.rest_prefix + '_' + self.cap4get_cred \ if self.cap4get_cred else '' if '--get-clear-credential--' in self.callerArgs.data and \ cap4get_cred and cap4get_cred not in current_caps: RH_Err.ctl(403, msgx='capability=' + cap4get_cred, logLevel=logging.INFO)
def __init__(self, *args, **kwargs): admin.MConfigHandler.__init__(self, *args, **kwargs) self._log_request() # check required attributes assert getattr(self, "endpoint", ''), \ RH_Err.ctl(1002, msgx='%s.endpoint' % (self._getHandlerName()), shouldPrint=False) assert hasattr(self, "validate") and ismethod(self.validate), \ RH_Err.ctl(1002, msgx='%s.validate' % (self._getHandlerName()), shouldPrint=False) assert hasattr(self, "normalize") and ismethod(self.normalize), \ RH_Err.ctl(1002, msgx='%s.normalize' % (self._getHandlerName()), shouldPrint=False) # check object name while creating self.check_name() # check capabilities of sessioned user self.check_caps() # Check if entry exists for "_sync" if self.customAction == '_sync': try: self.get(self.callerArgs.id) except ResourceNotFound: self.exist4sync = False except Exception, exc: RH_Err.ctl(1102, msgx='object=%s, err=%s' % (self.callerArgs.id, exc)) else: self.exist4sync = True
def __init__(self, *args, **kwargs): admin.MConfigHandler.__init__(self, *args, **kwargs) self._log_request() # not allow to create object with name starting with '_' if (self.requestedAction == admin.ACTION_CREATE and self.callerArgs.id and self.callerArgs.id.startswith('_')): RH_Err.ctl(400, msgx='It is not allowed to create object with ' 'name starting with "_"', logLevel=logging.INFO) # check required attributes assert getattr(self, "endpoint", ''), \ RH_Err.ctl(1002, msgx='%s.endpoint' % (self._getHandlerName()), shouldPrint=False) assert hasattr(self, "validate") and ismethod(self.validate), \ RH_Err.ctl(1002, msgx='%s.validate' % (self._getHandlerName()), shouldPrint=False) assert hasattr(self, "normalize") and ismethod(self.normalize), \ RH_Err.ctl(1002, msgx='%s.normalize' % (self._getHandlerName()), shouldPrint=False) # check object name while creating self.check_name() # check capabilities of sessioned user self.check_caps() # Check if entry exists for "_sync" if self.customAction == '_sync': try: self.get(self.callerArgs.id) except ResourceNotFound: self.exist4sync = False except Exception as exc: RH_Err.ctl(1102, msgx='object=%s, err=%s' % (self.callerArgs.id, exc)) else: self.exist4sync = True self._cred_mgmt = self.get_cred_mgmt(self.endpoint)
def handleRemove(self, confInfo): try: self.delete(self.callerArgs.id) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO) self._cred_mgmt.delete(self._makeStanzaName(self.callerArgs.id))
shouldPrint=False, shouldRaise=False, ) # read conf if self.callerArgs.id is None: ents = self.all() for name, ent in ents.items(): makeConfItem(name, ent, confInfo, user=user, app=app) else: try: ent = self.get(self.callerArgs.id) makeConfItem(self.callerArgs.id, ent, confInfo, user=user, app=app) except ResourceNotFound as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO) def handleReload(self, confInfo): self._reload(confInfo) def handleACL(self, confInfo): ent = self.get(self.callerArgs.id) meta = ent[admin.EAI_ENTRY_ACL] if self.requestedAction != admin.ACTION_LIST: if self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT] \ and len(self.callerArgs.data) > 0: ent.properties = dict()