-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #157 from multiflexi/e-mail_publisher
Improvements of email publisher - EMAIL UPDATE 2/2
- Loading branch information
Showing
7 changed files
with
160 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ src/.env | |
*.key | ||
*.log | ||
*.crt | ||
*.asc | ||
local/ | ||
|
||
# settings of editors | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# A directory for certificates and private keys | ||
|
||
If you wish to sign or encrypt messages of Taranis NG, place the certificates here. Use either PEM file with both certificate and key for S/MIME or armored PGP for signing. | ||
The signing file might be encrypted, you can specify the password in Taranis NG configuration. | ||
For encryption include S/MIME certificate or armored PGP public key. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,154 +1,120 @@ | ||
import datetime | ||
import smtplib | ||
from email.message import Message | ||
from email.mime.base import MIMEBase | ||
from email.mime.multipart import MIMEMultipart | ||
from email.mime.text import MIMEText | ||
import gnupg | ||
|
||
"""Publisher for publishing by email.""" | ||
from datetime import datetime | ||
from base64 import b64decode | ||
import os | ||
from managers import log_manager | ||
from .base_publisher import BasePublisher | ||
from shared.schema.parameter import Parameter, ParameterType | ||
from envelope import Envelope | ||
import mimetypes | ||
|
||
|
||
class EMAILPublisher(BasePublisher): | ||
"""_summary_. | ||
Arguments: | ||
BasePublisher -- _description_ | ||
Returns: | ||
_description_ | ||
""" | ||
|
||
type = "EMAIL_PUBLISHER" | ||
name = "EMAIL Publisher" | ||
description = "Publisher for publishing by email" | ||
|
||
parameters = [ | ||
Parameter(0, "SMTP_SERVER", "SMTP server", "SMTP server for sending emails", ParameterType.STRING), | ||
Parameter(0, "SMTP_SERVER_PORT", "SMTP server port", "SMTP server port for sending emails", | ||
ParameterType.STRING), | ||
Parameter(0, "SMTP_SERVER_PORT", "SMTP server port", "SMTP server port for sending emails", ParameterType.STRING), | ||
Parameter(0, "EMAIL_USERNAME", "Email username", "Username for email account", ParameterType.STRING), | ||
Parameter(0, "EMAIL_PASSWORD", "Email password", "Password for email account", ParameterType.STRING), | ||
Parameter(0, "EMAIL_RECIPIENT", "Email recipient", "Email address of recipient", ParameterType.STRING), | ||
Parameter(0, "EMAIL_SENDER", "Email sender", "Email address of the sender", ParameterType.STRING), | ||
Parameter(0, "EMAIL_RECIPIENT", "Email recipient", "Email address of the recipient", ParameterType.STRING), | ||
Parameter(0, "EMAIL_SUBJECT", "Email subject", "Text of email subject", ParameterType.STRING), | ||
Parameter(0, "EMAIL_MESSAGE", "Email message", "Text of email message", ParameterType.STRING), | ||
Parameter(0, "EMAIL_ENCRYPTION", "Do you want use email encrypt (yes/no)", "Turn ON/OFF email encryption", | ||
ParameterType.STRING) | ||
Parameter(0, "EMAIL_SIGN", "Email signature", "File used for signing or auto", ParameterType.STRING), | ||
Parameter(0, "EMAIL_SIGN_PASSWORD", "Email signature password", "Password for signing file", ParameterType.STRING), | ||
Parameter(0, "EMAIL_ENCRYPT", "Email encryption", "File used for encryption or auto", ParameterType.STRING), | ||
] | ||
|
||
parameters.extend(BasePublisher.parameters) | ||
|
||
def publish(self, publisher_input): | ||
|
||
smtp_server = publisher_input.parameter_values_map['SMTP_SERVER'] | ||
smtp_server_port = publisher_input.parameter_values_map['SMTP_SERVER_PORT'] | ||
email_user = publisher_input.parameter_values_map['EMAIL_USERNAME'] | ||
email_password = publisher_input.parameter_values_map['EMAIL_PASSWORD'] | ||
email_recipients = publisher_input.parameter_values_map['EMAIL_RECIPIENT'] | ||
email_subject = publisher_input.parameter_values_map['EMAIL_SUBJECT'] | ||
email_message = publisher_input.parameter_values_map['EMAIL_MESSAGE'] | ||
email_encryption = publisher_input.parameter_values_map['EMAIL_ENCRYPTION'] | ||
|
||
file = 'file_' + datetime.datetime.now().strftime("%d-%m-%Y_%H:%M") + '.pdf' | ||
|
||
if publisher_input.data is not None: | ||
data = publisher_input.data[:] | ||
"""_summary_. | ||
Arguments: | ||
publisher_input -- _description_ | ||
Returns: | ||
_description_ | ||
""" | ||
smtp_server = publisher_input.parameter_values_map["SMTP_SERVER"] | ||
smtp_server_port = publisher_input.parameter_values_map["SMTP_SERVER_PORT"] | ||
user = publisher_input.parameter_values_map["EMAIL_USERNAME"] | ||
password = publisher_input.parameter_values_map["EMAIL_PASSWORD"] | ||
sender = publisher_input.parameter_values_map["EMAIL_SENDER"] | ||
recipients = publisher_input.parameter_values_map["EMAIL_RECIPIENT"] | ||
subject = publisher_input.parameter_values_map["EMAIL_SUBJECT"] | ||
message = publisher_input.parameter_values_map["EMAIL_MESSAGE"] | ||
sign = publisher_input.parameter_values_map["EMAIL_SIGN"] | ||
sign_password = publisher_input.parameter_values_map["EMAIL_SIGN_PASSWORD"] | ||
encrypt = publisher_input.parameter_values_map["EMAIL_ENCRYPT"] | ||
|
||
now = datetime.now().strftime("%Y%m%d%H%M%S") | ||
|
||
smtp = {"host": smtp_server, "port": smtp_server_port, "user": user, "password": password} | ||
|
||
envelope = Envelope() | ||
|
||
# if attachment data available from presenter | ||
if publisher_input.mime_type and publisher_input.data: | ||
attachment_mimetype = publisher_input.mime_type | ||
attachment_extension = mimetypes.guess_extension(attachment_mimetype) | ||
attachment_data = publisher_input.data[:] | ||
attachment_list = [ | ||
( | ||
b64decode(attachment_data), | ||
attachment_mimetype, | ||
f"file_{now}{attachment_extension}", | ||
False, | ||
) | ||
] | ||
# it is possible to attach multiple files | ||
envelope.attach(attachment_list) | ||
|
||
# when title available from presenter | ||
if publisher_input.message_title: | ||
subject = b64decode(publisher_input.message_title).decode("UTF-8") | ||
# when body available from presenter | ||
if publisher_input.message_body: | ||
message = b64decode(publisher_input.message_body).decode("UTF-8") | ||
|
||
if not message: | ||
envelope.message(" ") | ||
else: | ||
data = None | ||
|
||
def get_attachment(file_name): | ||
msg_attachment = Message() | ||
msg_attachment.add_header(_name="Content-Type", _value='application/pdf', name=file_name) | ||
msg_attachment.add_header(_name="Content-Transfer-Encoding", _value="base64") | ||
msg_attachment.add_header(_name="Content-Disposition", _value="attachment", filename=file_name) | ||
msg_attachment.set_payload(data) | ||
return msg_attachment | ||
|
||
def get_body(message): | ||
msg_body = Message() | ||
msg_body.add_header(_name="Content-Type", _value="text/plain", charset="utf-8") | ||
msg_body.add_header(_name="Content-Transfer-Encoding", _value="quoted-printable") | ||
msg_body.set_payload(message + 2 * "\n") | ||
return msg_body | ||
|
||
def get_encrypted_email_string(email_address_recipient, file_name, message): | ||
def get_gpg_cipher_text(string, recipient_email_address): | ||
gpg = gnupg.GPG() | ||
encrypted_str = str(gpg.encrypt(string, recipient_email_address)) | ||
return encrypted_str | ||
|
||
msg = Message() | ||
msg.add_header(_name="Content-Type", _value="multipart/mixed") | ||
msg["From"] = email_user | ||
msg["To"] = email_address_recipient | ||
msg['Subject'] = email_subject | ||
|
||
msg_text = Message() | ||
msg_text.add_header(_name="Content-Type", _value="multipart/mixed") | ||
msg_text.add_header(_name="Content-Language", _value="en-US") | ||
|
||
msg_body = get_body(message) | ||
msg_attachment = get_attachment(file_name) | ||
|
||
msg_text.attach(msg_body) | ||
msg_text.attach(msg_attachment) | ||
msg.attach(msg_text) | ||
|
||
pgp_msg = MIMEBase(_maintype="multipart", _subtype="encrypted", protocol="application/pgp-encrypted") | ||
pgp_msg["From"] = email_user | ||
pgp_msg["To"] = email_address_recipient | ||
pgp_msg['Subject'] = email_subject | ||
|
||
pgp_msg_part1 = Message() | ||
pgp_msg_part1.add_header(_name="Content-Type", _value="application/pgp-encrypted") | ||
pgp_msg_part1.add_header(_name="Content-Description", _value="PGP/MIME version identification") | ||
pgp_msg_part1.set_payload("Version: 2" + "\n") | ||
|
||
pgp_msg_part2 = Message() | ||
pgp_msg_part2.add_header(_name="Content-Type", _value="application/octet-stream", name="encrypted.asc") | ||
pgp_msg_part2.add_header(_name="Content-Description", _value="OpenPGP encrypted message") | ||
pgp_msg_part2.add_header(_name="Content-Disposition", _value="inline", filename="encrypted.asc") | ||
pgp_msg_part2.set_payload(get_gpg_cipher_text(msg.as_string(), email_address_recipient)) | ||
|
||
pgp_msg.attach(pgp_msg_part1) | ||
pgp_msg.attach(pgp_msg_part2) | ||
|
||
return pgp_msg.as_string() | ||
envelope.message(message) | ||
if not subject: | ||
envelope.subject(" ") | ||
else: | ||
envelope.subject(subject) | ||
envelope.from_(sender) | ||
envelope.to(recipients) | ||
envelope.smtp(smtp) | ||
|
||
if sign == "auto": | ||
envelope.signature(key=sign) | ||
elif os.path.isfile(sign): | ||
log_manager.log_info(f"Signing email with file {sign}") | ||
envelope.signature(key=open(sign), passphrase=sign_password) | ||
|
||
if encrypt == "auto": | ||
envelope.encryption(key=encrypt) | ||
elif os.path.isfile(encrypt): | ||
log_manager.log_info(f"Encrypting email with file {encrypt}") | ||
envelope.encryption(key=open(encrypt)) | ||
|
||
try: | ||
|
||
server = smtplib.SMTP(smtp_server, smtp_server_port) | ||
server.starttls() | ||
server.login(email_user, email_password) | ||
|
||
if publisher_input.recipients is not None: | ||
recipients = publisher_input.recipients | ||
else: | ||
recipients = email_recipients.split(',') | ||
|
||
if email_encryption.lower() == 'yes': | ||
for recipient in recipients: | ||
email_msg = email_message | ||
email_msg = get_encrypted_email_string(recipient, file, email_msg) | ||
server.sendmail(email_user, recipient, email_msg) | ||
else: | ||
email_msg = MIMEMultipart() | ||
email_msg['From'] = email_user | ||
email_msg['To'] = email_recipients | ||
|
||
if publisher_input.message_title is not None: | ||
email_msg['Subject'] = publisher_input.message_title | ||
else: | ||
email_msg['Subject'] = email_subject | ||
|
||
if publisher_input.message_body is not None: | ||
body = publisher_input.message_body | ||
else: | ||
body = email_message | ||
|
||
email_msg.attach(MIMEText(body + 2 * "\n", 'plain')) | ||
|
||
if data is not None: | ||
attachment = get_attachment(file) | ||
email_msg.attach(attachment) | ||
|
||
text = email_msg.as_string() | ||
|
||
server.sendmail(email_user, recipients, text) | ||
|
||
server.quit() | ||
envelope.send() | ||
|
||
except Exception as error: | ||
BasePublisher.print_exception(self, error) |
Oops, something went wrong.