123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- ###############################################################################
- # #
- # L3q - Light, light, lightweight queue #
- # Copyright (C) 2023 Marcus Pedersén marcus.pedersen@slu.se #
- # #
- # This program is free software: you can redistribute it and/or modify #
- # it under the terms of the GNU General Public License as published by #
- # the Free Software Foundation, either version 3 of the License, or #
- # (at your option) any later version. #
- # #
- # This program 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 General Public License for more details. #
- # #
- # You should have received a copy of the GNU General Public License #
- # along with this program. If not, see <http://www.gnu.org/licenses/>. #
- # #
- ###############################################################################
- import sys
- import os
- import grp
- import configparser
- '''
- This module contains common classes
- and functions for all L3q client programs.
- '''
- CONF_FILE = '/etc/l3q/l3q.conf'
- class L3QConfig:
- '''
- Contains the needed configuration
- for the L3Queue clients.
- On failure program will terminate.
- Variables:
- validate_mode
- validate_uid
- are required permission and owner
- for validate file.
- '''
- validate_mode = 0o100440
- validate_uid = 0
- def __init__(self, parse_validate:bool=True) -> None:
- '''
- Init will read config file:
- /etc/l3q/l3q.conf
- If values are missing default
- values will be used.
- Validate file will also be checked
- and read.
- If any error occures error will be
- printed and program will terminate
- with non zero exit code.
- '''
- self.set_defaults()
- self.get_config()
- # After config is parsed and before
- # validation file is read,
- # check if user is part of group self.group
- # or is root
- member_of_group = False
- for gid in os.getgroups():
- gname = grp.getgrgid(gid)
- if(gname.gr_name == self.group or gid == 0):
- member_of_group = True
- if(not member_of_group):
- print('Permission denied.', file=sys.stderr)
- exit(1)
-
- if(parse_validate):
- self.get_validate()
- def set_defaults(self) -> None:
- '''
- Sets the default config values
- '''
- self.l3qd_host:str = ''
- self.l3qd_port:int = 39911
- self.group:str = 'l3q'
- self.validate_file:str = '/etc/l3q/network.l3q'
- self.log_file:str = '/var/log/l3q/l3q-client.log'
- self.validate_key:str = ''
-
- def get_config(self) -> None:
- '''
- Reads config file and populates
- object with values read from file.
- '''
- conf = configparser.ConfigParser()
- conf.read(CONF_FILE)
- if(not conf.has_section('l3q_daemon')):
- print('Error reading config file:', file=sys.stderr)
- print(CONF_FILE, file=sys.stderr)
- print('Check configuration of client tools', file=sys.stderr)
- sys.exit(1)
- if(not conf.has_option('l3q_daemon', 'l3qd_host')):
- print('Required parameter \'l3qd_host\' is missing in config file:', file=sys.stderr)
- print(CONF_FILE, file=sys.stderr)
- print('Check configuration of client tools', file=sys.stderr)
- sys.exit(2)
- self.l3qd_host = conf['l3q_daemon']['l3qd_host']
- if(conf.has_option('l3q_daemon', 'l3qd_port')):
- if(not conf['l3q_daemon']['l3qd_port'].isdigit()):
- print('Parse error in config file:', file=sys.stderr)
- print(CONF_FILE, file=sys.stderr)
- print('Parameter l3qd_port must be an integer', file=sys.stderr)
- sys.exit(3)
- else:
- self.l3qd_port = int(conf['l3q_daemon']['l3qd_port'])
- if(conf.has_option('l3q_client', 'validate_file')):
- self.validate_file = conf['l3q_client']['validate_file']
- if(conf.has_option('l3q_client', 'log_file')):
- self.log_file = conf['l3q_client']['log_file']
-
- if(conf.has_option('l3q_client', 'group')):
- self.group = conf['l3q_client']['group']
- def get_validate(self) -> None:
- '''
- Checks permissions and owner of
- the validation file, terminates
- program on failure.
- Puts validation sting in this object.
- First line of validation file is read
- so first line must contain validation key.
- File must only contain validate key.
- '''
- if(not os.path.exists(self.validate_file)):
- print('Validate file: {}'.format(self.validate_file), file=sys.stderr)
- print('Does not exist', file=sys.stderr)
- print('Configure verification with L3q daemon', file=sys.stderr)
- sys.exit(4)
-
- stat = os.stat(self.validate_file)
- if(int(stat.st_size) == 0):
- print('Validate file: {}'.format(self.validate_file), file=sys.stderr)
- print('Have zero size', file=sys.stderr)
- print('Configure verification with L3q daemon', file=sys.stderr)
- sys.exit(5)
- if(int(stat.st_mode) != L3QConfig.validate_mode):
- print('Validate file: {}'.format(self.validate_file), file=sys.stderr)
- print('has wrong file permissions', file=sys.stderr)
- print('Required mode is: {}'.format(oct(L3QConfig.validate_mode - 0o100000)[2:]), file=sys.stderr)
- sys.exit(6)
- if(int(stat.st_uid) != L3QConfig.validate_uid):
- print('Validate file: {}'.format(self.validate_file), file=sys.stderr)
- print('has wrong file owner', file=sys.stderr)
- print('Required owner is: root', file=sys.stderr)
- sys.exit(7)
- if(grp.getgrgid(stat.st_gid)[0] != self.group):
- print('Validate file: {}'.format(self.validate_file), file=sys.stderr)
- print('has wrong file group', file=sys.stderr)
- print('Required group is: {}'.format(self.group), file=sys.stderr)
- sys.exit(8)
- try:
- with open(self.validate_file) as f:
- self.validate_key = f.readline().strip()
- except Exception as e:
- print('Validate file: {}'.format(self.validate_file), file=sys.stderr)
- print('Error reading file', file=sys.stderr)
- print('{}'.format(e), file=sys.stderr)
- sys.exit(9)
|