diff --git a/src/freenas/etc/find_alias_for_smtplib.py b/src/freenas/etc/find_alias_for_smtplib.py index cd52a48957288..a237bd3218025 100755 --- a/src/freenas/etc/find_alias_for_smtplib.py +++ b/src/freenas/etc/find_alias_for_smtplib.py @@ -2,133 +2,125 @@ import email import email.parser import json -import os -import re import requests import sys -import syslog from truenas_api_client import Client -ALIASES = re.compile(r'^(?P[^#]\S*?):\s*(?P\S+)$') - def do_sendmail(msg, to_addrs=None, parse_recipients=False): + to_addrs = ["root"] if to_addrs is None else to_addrs + if to_addrs is None and not parse_recipients: + raise ValueError("Do not know who to send the message to.") - if to_addrs is None: - if not parse_recipients: - syslog.syslog('Do not know who to send the message to.' + msg[0:140]) - raise ValueError('Do not know who to send the message to.') - to_addrs = [] - - # XXX: this should probably be a FeedParser because reading from sys.stdin - # is blocking. - em_parser = email.parser.Parser() - em = em_parser.parsestr(msg) + em = email.parser.Parser().parsestr(msg) if parse_recipients: # Strip away the comma based delimiters and whitespace. - to_addrs = list(map(str.strip, em.get('To').split(','))) - - if not to_addrs or not to_addrs[0]: - to_addrs = ['root'] + for addr in map(str.strip, em.get("To", "").split(",")): + if addr: + to_addrs.append(addr) to_addrs_repl = [] - if to_addrs: - aliases = get_aliases() - for to_addr in to_addrs: - for to_addr in to_addr.split(','): - if to_addr.find('@') != -1: - to_addrs_repl.append(to_addr) - elif to_addr.find('@') == -1 and to_addr in aliases: - to_addrs_repl.append(aliases[to_addr]) + aliases = get_aliases() + for i in to_addrs: + for to_addr in i.split(","): + if "@" in to_addr: + to_addrs_repl.append(to_addr) + elif to_addr in aliases: + to_addrs_repl.append(aliases[to_addr]) if not to_addrs_repl: - syslog.syslog(f'No aliases found to send email to {", ".join(to_addrs)}') + print( + f'No aliases found to send email to {", ".join(to_addrs)}', file=sys.stderr + ) sys.exit(1) with Client() as c: - sw_name = 'TrueNAS' - - margs = {} - margs['extra_headers'] = dict(em) - margs['extra_headers'].update({ - 'X-Mailer': sw_name, - f'X-{sw_name}-Host': c.call('system.hostname'), - 'To': ', '.join(to_addrs_repl), - }) - margs['subject'] = em.get('Subject') - + sw_name = "TrueNAS" + margs = dict() + margs["extra_headers"] = dict(em) + margs["extra_headers"].update( + { + "X-Mailer": sw_name, + f"X-{sw_name}-Host": c.call("system.hostname"), + "To": ", ".join(to_addrs_repl), + } + ) + margs["subject"] = em.get("Subject") if em.is_multipart(): - attachments = [part for part in em.walk() if part.get_content_maintype() != 'multipart'] - margs['attachments'] = True if attachments else False - margs['text'] = ( - 'This is a MIME formatted message. If you see ' - 'this text it means that your email software ' - 'does not support MIME formatted messages.') - margs['html'] = None + attachments = [ + part for part in em.walk() if part.get_content_maintype() != "multipart" + ] + margs["attachments"] = True if attachments else False + margs["text"] = ( + "This is a MIME formatted message. If you see " + "this text it means that your email software " + "does not support MIME formatted messages." + ) + margs["html"] = None else: - margs['text'] = ''.join(email.iterators.body_line_iterator(em)) - - margs['to'] = to_addrs_repl + margs["text"] = "".join(email.iterators.body_line_iterator(em)) - if not margs.get('attachments'): - c.call('mail.send', margs) + margs["to"] = to_addrs_repl + if not margs.get("attachments"): + c.call("mail.send", margs) else: - token = c.call('auth.generate_token') + token = c.call("auth.generate_token") files = [] for attachment in attachments: - entry = {'headers': []} + entry = {"headers": []} for k, v in attachment.items(): - entry['headers'].append({'name': k, 'value': v}) - entry['content'] = attachment.get_payload() + entry["headers"].append({"name": k, "value": v}) + entry["content"] = attachment.get_payload() files.append(entry) requests.post( - f'http://localhost:6000/_upload?auth_token={token}', + f"http://localhost:6000/_upload?auth_token={token}", files={ - 'data': json.dumps({'method': 'mail.send', 'params': [margs]}), - 'file': json.dumps(files), + "data": json.dumps({"method": "mail.send", "params": [margs]}), + "file": json.dumps(files), }, ) def get_aliases(): - with open('/etc/aliases', 'r') as f: - aliases = {} - - for line in f.readlines(): - search = ALIASES.search(line) - if search: - _from, _to = search.groups() - aliases[_from] = _to - - while True: - oldaliases = set(aliases.items()) - for key, val in aliases.items(): - if key == val: - syslog.syslog(syslog.LOG_ERR, f'Found a recursive dependency for {key}') - elif val in aliases: - aliases[key] = aliases[val] - if set(aliases.items()) == oldaliases: - break - return aliases + aliases = {} + with open("/etc/aliases", "r") as f: + for line in f: + # looks like + # admin1: name@domain.com, another@domain.com + # admin2: name@domain.com + try: + name, addresses = line.strip().split(":") + if name != addresses: + aliases[name] = addresses + except ValueError: + continue + return aliases def main(): - syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_MAIL) - parser = argparse.ArgumentParser(description='Process email') - parser.add_argument('-i', dest='strip_leading_dot', action='store_false', - default=True, help='see sendmail(8) -i') - parser.add_argument('-t', dest='parse_recipients', action='store_true', - default=False, - help='parse recipients from message') - parser.usage = ' '.join(parser.format_usage().split(' ')[1:-1]) - parser.usage += ' [email_addr|user] ..' + parser = argparse.ArgumentParser(description="Process email") + parser.add_argument( + "-i", + dest="strip_leading_dot", + action="store_false", + default=True, + help="see sendmail(8) -i", + ) + parser.add_argument( + "-t", + dest="parse_recipients", + action="store_true", + default=False, + help="parse recipients from message", + ) + parser.usage = " ".join(parser.format_usage().split(" ")[1:-1]) + parser.usage += " [email_addr|user] .." args, to = parser.parse_known_args() if not to and not args.parse_recipients: parser.exit(message=parser.format_usage()) msg = sys.stdin.read() - syslog.syslog("sending mail to " + ', '.join(to) + '\n' + msg[0:140]) do_sendmail(msg, to_addrs=to, parse_recipients=args.parse_recipients) diff --git a/src/middlewared/middlewared/plugins/cron.py b/src/middlewared/middlewared/plugins/cron.py index 9804db52238c7..605dd06d20d36 100644 --- a/src/middlewared/middlewared/plugins/cron.py +++ b/src/middlewared/middlewared/plugins/cron.py @@ -1,6 +1,5 @@ import contextlib import errno -import syslog from middlewared.schema import accepts, Bool, Cron, Dict, Int, Patch, returns, Str from middlewared.service import CallError, CRUDService, job, private, ValidationErrors @@ -209,10 +208,6 @@ def run(self, job, id_, skip_disabled): """ Job to run cronjob task of `id`. """ - def __cron_log(line): - job.logs_fd.write(line) - syslog.syslog(syslog.LOG_INFO, line.decode()) - cron_task = self.middleware.call_sync('cronjob.get_instance', id_) if skip_disabled and not cron_task['enabled']: raise CallError('Cron job is disabled', errno.EINVAL) @@ -224,26 +219,11 @@ def __cron_log(line): )[7:] ) - job.set_progress( - 10, - 'Executing Cron Task' - ) - - syslog.openlog('cron', facility=syslog.LOG_CRON) - - syslog.syslog(syslog.LOG_INFO, f'({cron_task["user"]}) CMD ({cron_cmd})') - - cp = run_command_with_user_context( - cron_cmd, cron_task['user'], callback=__cron_log, - ) - - syslog.closelog() + job.set_progress(10, 'Executing Cron Task') - job.set_progress( - 85, - 'Executed Cron Task' - ) + cp = run_command_with_user_context(cron_cmd, cron_task['user'], callback=job.logs_fd.write) + job.set_progress(85, 'Executed Cron Task') if cp.stdout: email = ( self.middleware.call_sync('user.query', [['username', '=', cron_task['user']]], {'get': True}) diff --git a/src/middlewared/middlewared/plugins/mail.py b/src/middlewared/middlewared/plugins/mail.py index 3409df41c3958..78db874c0649e 100644 --- a/src/middlewared/middlewared/plugins/mail.py +++ b/src/middlewared/middlewared/plugins/mail.py @@ -21,7 +21,6 @@ import json import os import smtplib -import syslog class DenyNetworkActivity(Exception): @@ -369,7 +368,6 @@ def read_json(): else: msg[key] = val - syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_MAIL) try: if config['oauth']: self.middleware.call_sync('mail.gmail_send', msg, config) @@ -383,20 +381,15 @@ def read_json(): # This is because FreeNAS doesn't run a full MTA. # else: # server.connect() - headers = '\n'.join([f'{k}: {v}' for k, v in msg._headers]) - syslog.syslog(f"sending mail to {', '.join(to)}\n{headers}") server.sendmail(from_addr.encode(), to, msg.as_string()) server.quit() except DenyNetworkActivity: self.logger.warning('Sending email denied') return False except Exception as e: - # Don't spam syslog with these messages. They should only end up in the - # test-email pane. # We are only interested in ValueError, not subclasses. if e.__class__ is ValueError: raise CallError(str(e)) - syslog.syslog(f'Failed to send email to {", ".join(to)}: {str(e)}') if isinstance(e, smtplib.SMTPAuthenticationError): raise CallError( f'Authentication error ({e.smtp_code}): {e.smtp_error}', errno.EPERM diff --git a/src/middlewared/middlewared/plugins/ssh.py b/src/middlewared/middlewared/plugins/ssh.py index ad406cc85406b..3bba21c00a56a 100644 --- a/src/middlewared/middlewared/plugins/ssh.py +++ b/src/middlewared/middlewared/plugins/ssh.py @@ -1,8 +1,6 @@ import base64 -import hashlib import os import subprocess -import syslog import middlewared.sqlalchemy as sa @@ -163,18 +161,6 @@ async def do_update(self, data): await self._update_service(old, new) - keyfile = "/usr/local/etc/ssh/ssh_host_ecdsa_key.pub" - if os.path.exists(keyfile): - with open(keyfile, "rb") as f: - pubkey = f.read().strip().split(None, 3)[1] - decoded_key = base64.b64decode(pubkey) - key_digest = hashlib.sha256(decoded_key).digest() - ssh_fingerprint = (b"SHA256:" + base64.b64encode(key_digest).replace(b"=", b"")).decode("utf-8") - - syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_USER) - syslog.syslog(syslog.LOG_ERR, 'ECDSA Fingerprint of the SSH KEY: ' + ssh_fingerprint) - syslog.closelog() - return await self.config() keys = [ diff --git a/src/middlewared/middlewared/plugins/system_general/update.py b/src/middlewared/middlewared/plugins/system_general/update.py index e9091d3bdc274..910bd6ec5cfbb 100644 --- a/src/middlewared/middlewared/plugins/system_general/update.py +++ b/src/middlewared/middlewared/plugins/system_general/update.py @@ -1,5 +1,4 @@ import asyncio -import syslog import middlewared.sqlalchemy as sa @@ -181,18 +180,12 @@ async def validate_general_settings(self, data, old_config, schema): 'Please specify a valid certificate which exists in the system' ) else: - cert = cert[0] verrors.extend( await self.middleware.call( 'certificate.cert_services_validation', certificate_id, f'{schema}.ui_certificate', False ) ) - if cert['fingerprint']: - syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_USER) - syslog.syslog(syslog.LOG_ERR, 'Fingerprint of the certificate used in UI : ' + cert['fingerprint']) - syslog.closelog() - return verrors @accepts( diff --git a/src/middlewared/middlewared/plugins/ups.py b/src/middlewared/middlewared/plugins/ups.py index 5e22854288abd..5f20cb0224d35 100644 --- a/src/middlewared/middlewared/plugins/ups.py +++ b/src/middlewared/middlewared/plugins/ups.py @@ -4,7 +4,6 @@ import io import os import re -import syslog from middlewared.schema import accepts, Bool, Dict, Int, List, Patch, returns, Str from middlewared.service import private, SystemServiceService, ValidationErrors @@ -313,13 +312,11 @@ async def upssched_event(self, notify_type): # first and then shut the active node down if await self.middleware.call('failover.licensed'): if await self.middleware.call('failover.status') == 'MASTER': - syslog.syslog(syslog.LOG_NOTICE, 'upssched-cmd "issuing shutdown" for passive node') try: await self.middleware.call('failover.call_remote', 'ups.upssched_event', ['shutdown']) - except Exception as e: - syslog.syslog(syslog.LOG_ERR, f'failed shutting down passive node with error {e}') + except Exception: + self.logger.error('failed shutting down passive node', exc_info=True) - syslog.syslog(syslog.LOG_NOTICE, 'upssched-cmd "issuing shutdown"') await run('upsmon', '-c', 'fsd', check=False) elif 'notify' in notify_type.lower(): diff --git a/src/middlewared/middlewared/utils/syslog.py b/src/middlewared/middlewared/utils/syslog.py index 6fef4886f8392..2fc5139def322 100644 --- a/src/middlewared/middlewared/utils/syslog.py +++ b/src/middlewared/middlewared/utils/syslog.py @@ -1,19 +1,12 @@ -import os import syslog -import uuid from middlewared.utils.time_utils import utc_now def syslog_message(message): data = f'<{syslog.LOG_USER | syslog.LOG_INFO}>' - data += f'{utc_now().strftime("%b %d %H:%M:%S")} ' - data += 'TNAUDIT_MIDDLEWARE: ' - data += message - data = data.encode('ascii', 'ignore') - return data