# -*- coding: utf-8 -*-## License: AGPLv3# This file is part of eduMFA. eduMFA is a fork of privacyIDEA which was forked from LinOTP.# Copyright (c) 2024 eduMFA Project-Team# Previous authors by privacyIDEA project:## 2015 - 2016 Cornelius Kölbel <cornelius@privacyidea.org>## This code is free software; you can redistribute it and/or# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE# License as published by the Free Software Foundation; either# version 3 of the License, or any later version.## This code is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU AFFERO GENERAL PUBLIC LICENSE for more details.## You should have received a copy of the GNU Affero General Public# License along with this program. If not, see <http://www.gnu.org/licenses/>.#__doc__="""This contains the HostsMachineResolver which simply resolvesthe machines in a file like /etc/hosts.The machine id is the IP address in this case.This file is tested in tests/test_lib_machines.py in the classHostsMachineTestCase"""from.baseimportMachinefrom.baseimportBaseMachineResolverfrom.baseimportMachineResolverErrorimportnetaddr
[docs]defget_machines(self,machine_id=None,hostname=None,ip=None,any=None,substring=False):""" Return matching machines. :param machine_id: can be matched as substring :param hostname: can be matched as substring :param ip: can not be matched as substring :param substring: Whether the filtering should be a substring matching :type substring: bool :param any: a substring that matches EITHER hostname, machineid or ip :type any: basestring :return: list of Machine Objects """machines=[]f=open(self.filename,"r")try:forlineinf:split_line=line.split()iflen(split_line)<2:# skip lines with less than 2 columnscontinueifsplit_line[0][0]=="#":# skip commentscontinueline_id=split_line[0]line_ip=netaddr.IPAddress(split_line[0])line_hostname=split_line[1:]# check if machine_id, ip or hostname matches a substringif(anyandanynotinline_idandlen([xforxinline_hostnameifanyinx])<=0andanynotin"{0!s}".format(line_ip)):# "any" was provided but did not match either# hostname, ip or machine_idcontinueelse:ifmachine_id:ifnotsubstringandmachine_id==line_id:return[Machine(self.name,line_id,hostname=line_hostname,ip=line_ip)]ifsubstringandmachine_idnotinline_id:# do not append this machine!continueifhostname:ifsubstring:h_match=len([xforxinline_hostnameifhostnameinx])else:h_match=hostnameinline_hostnameifnoth_match:# do not append this machine!continueifipandip!=line_ip:# Do not append this machine!continuemachines.append(Machine(self.name,line_id,hostname=line_hostname,ip=line_ip))finally:f.close()returnmachines
[docs]defget_machine_id(self,hostname=None,ip=None):""" Returns the machine id for a given hostname or IP address. If hostname and ip is given, the resolver should also check that the hostname matches the IP. If it can check this and hostname and IP do not match, then an Exception must be raised. :param hostname: The hostname of the machine :type hostname: basestring :param ip: IP address of the machine :type ip: netaddr :return: The machine ID, which depends on the resolver :rtype: basestring """machines=self.get_machines()formachineinmachines:h_match=nothostnameormachine.has_hostname(hostname)i_match=notipormachine.has_ip(ip)ifh_matchandi_match:returnmachine.idreturn
[docs]defload_config(self,config):""" This loads the configuration dictionary, which contains the necessary information for the machine resolver to find and connect to the machine store. :param config: The configuration dictionary to run the machine resolver :type config: dict :return: None """self.filename=config.get("filename")ifself.filenameisNone:raiseMachineResolverError("filename is missing!")