Generate Free DMARC Record and Save Instructions in a PDF using Python

What is DMARC?

Domain-based Message Authentication, Reporting, and Conformance (DMARC) is a standard for email authentication and reporting. DMARC helps organizations protect their email domains from being used for phishing and spoofing attacks. It allows senders to specify how mail servers should handle unauthenticated emails and provides a way to receive reports about email delivery and failures.

In this article, we will walk you through the process of creating a Python application that generates DMARC records based on user input and then saves these records, along with instructions on how to add them to a DNS (Domain Name System) server in a PDF document. We'll use the Tkinter library for the user interface and ReportLab for creating the PDF.

Prerequisites

Before you begin, make sure you have Python installed on your system. You'll also need to install the tkinter and reportlab packages if they are not already installed. You can do this using pip.

pip install tk
pip install reportlab

Understanding the Code

We'll break down the code into several parts to explain its functionality.

Importing Required Libraries

The code begins by importing the necessary libraries.

  • tkinter is used for creating the graphical user interface.
  • messagebox is used for displaying dialog boxes.
  • filedialog is used for opening and saving files.
  • reportlab is used for generating PDF documents.
import tkinter as tk
from tkinter import messagebox, filedialog
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT

Defining Functions

The code defines several functions.

  • generate_dmarc_record(): This function is called when the user clicks the "Generate DMARC Record" button. It collects user input, formats the DMARC record, creates instructions, and generates a PDF with this information.
  • generate_pdf(): This function takes the domain, DMARC record, and instructions as arguments and creates a PDF document with proper formatting using ReportLab.
  • main(): This is the main function where the Tkinter GUI is created. It defines input fields for the domain, RUA (Reporting URI for Aggregate reports), PCT (Percentage of messages subjected to filtering), policy (Policy for handling failed messages), and RUF (Reporting URI for Forensic reports). It also creates a "Generate DMARC Record" button to trigger the DMARC record generation.

User Interface

The user interface is created using Tkinter. Input fields for the domain, RUA, PCT, policy, and RUF are added to the main window. The "Generate DMARC Record" button is placed at the bottom.

root = tk.Tk()
root.title("DMARC Record Generator")

global domain, rua, pct, policy, ruf

input_fields = [
    ("Domain:", "example.com"),
    ("Reporting URI for Aggregate reports:", "[email protected]"),
    ("Percentage of messages subjected to filtering (0-100):", "100"),
    ("Policy for handling failed messages:", "none"),
    ("Reporting URI for Forensic reports:", "[email protected]")
]

entries = {}
for label_text, default_value in input_fields:
    label = tk.Label(root, text=label_text)
    label.pack()
    entry_var = tk.StringVar(value=default_value)
    entry = tk.Entry(root, textvariable=entry_var)
    entry.pack()
    if label_text == "Domain:":
        domain = entry_var
    elif label_text == "Reporting URI for Aggregate reports:":
        rua = entry_var
    elif label_text == "Percentage of messages subjected to filtering (0-100):":
        pct = entry_var
    elif label_text == "Policy for handling failed messages:":
        policy = entry_var
    elif label_text == "Reporting URI for Forensic reports:":
        ruf = entry_var
    entries[label_text] = entry

generate_button = tk.Button(root, text="Generate DMARC Record", command=generate_dmarc_record)
generate_button.pack()

Generating DMARC Records and PDFs

When the user clicks the "Generate DMARC Record" button, the generate_dmarc_record() function is called. It formats the user input to create a DMARC record and instructions. It then calls the generate_pdf() function to generate a PDF document and displays a message box to confirm the successful creation of the PDF.

def generate_dmarc_record():
    # Collect user input
    domain_value = domain.get()
    rua_value = rua.get()
    pct_value = pct.get()
    policy_value = policy.get()
    ruf_value = ruf.get()

    # Correctly format RUA and RUF values
    rua_value = f'mailto:{rua_value}' if not rua_value.startswith("mailto:") else rua_value
    ruf_value = f'mailto:{ruf_value}' if not ruf_value.startswith("mailto:") else ruf_value

    dmarc_record = f'v=DMARC1; p={policy_value}; rua={rua_value}; pct={pct_value}; ruf={ruf_value}'

    # Create formatted instructions
    instructions = [
        "Instructions to add the DMARC record to DNS:",
        "1. Log in to your DNS management portal or service provider.",
        "2. Locate the DNS records section and choose to edit or add a new DNS record.",
        "3. Create a new TXT record for your domain.",
        "4. Set the host or subdomain to '_dmarc' (without quotes).",
        "5. Set the value of the TXT record to the following DMARC record:",
        dmarc_record,
        "6. Save your changes and wait for the DNS record to propagate. It may take some time for changes to take effect."
    ]

    generate_pdf(domain_value, dmarc_record, instructions)

def generate_pdf(domain, dmarc_record, instructions):
    pdf_filename = filedialog.asksaveasfilename(defaultextension=".pdf", filetypes=[("PDF files", "*.pdf")])
    if not pdf_filename:
        return  # User canceled the save dialog

    doc = SimpleDocTemplate(pdf_filename, pagesize=letter)

    styles = getSampleStyleSheet()
    style = styles['Normal']
    style.alignment = TA_LEFT

    content = []
    content.append(Paragraph(f"DMARC Record for {domain}", styles['Heading1']))
    content.append(Spacer(1, 12))  # Add some space

    dmarc_paragraph = Paragraph(dmarc_record, style)
    content.append(dmarc_paragraph)

    content.append(Spacer(1, 24))  # Add more space

    instructions_heading = Paragraph("Instructions to add the DMARC record to DNS:", styles['Heading1'])
    content.append(instructions_heading)

    for instr in instructions:
        content.append(Paragraph(instr, style))

    doc.build(content)
    messagebox.showinfo("DMARC Record Created", f"DMARC record and instructions have been saved to {pdf_filename}.")

if __name__ == "__main__":
    main()

Full Code

import tkinter as tk
from tkinter import messagebox, filedialog
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT

def generate_dmarc_record():
    domain_value = domain.get()
    rua_value = rua.get()
    pct_value = pct.get()
    policy_value = policy.get()
    ruf_value = ruf.get()

    # Correctly format RUA and RUF values
    rua_value = f'mailto:{rua_value}' if not rua_value.startswith("mailto:") else rua_value
    ruf_value = f'mailto:{ruf_value}' if not ruf_value.startswith("mailto:") else ruf_value

    dmarc_record = f'v=DMARC1; p={policy_value}; rua={rua_value}; pct={pct_value}; ruf={ruf_value}'

    # Create formatted instructions
    instructions = [
        "Instructions to add the DMARC record to DNS:",
        "1. Log in to your DNS management portal or service provider.",
        "2. Locate the DNS records section and choose to edit or add a new DNS record.",
        "3. Create a new TXT record for your domain.",
        "4. Set the host or subdomain to '_dmarc' (without quotes).",
        "5. Set the value of the TXT record to the following DMARC record:",
        dmarc_record,
        "6. Save your changes and wait for the DNS record to propagate. It may take some time for changes to take effect."
    ]

    generate_pdf(domain_value, dmarc_record, instructions)

def generate_pdf(domain, dmarc_record, instructions):
    pdf_filename = filedialog.asksaveasfilename(defaultextension=".pdf", filetypes=[("PDF files", "*.pdf")])
    if not pdf_filename:
        return  # User canceled the save dialog

    doc = SimpleDocTemplate(pdf_filename, pagesize=letter)

    styles = getSampleStyleSheet()
    style = styles['Normal']
    style.alignment = TA_LEFT

    content = []
    content.append(Paragraph(f"DMARC Record for {domain}", styles['Heading1']))
    content.append(Spacer(1, 12))  # Add some space

    dmarc_paragraph = Paragraph(dmarc_record, style)
    content.append(dmarc_paragraph)

    content.append(Spacer(1, 24))  # Add more space

    instructions_heading = Paragraph("Instructions to add the DMARC record to DNS:", styles['Heading1'])
    content.append(instructions_heading)

    for instr in instructions:
        content.append(Paragraph(instr, style))

    doc.build(content)
    messagebox.showinfo("DMARC Record Created", f"DMARC record and instructions have been saved to {pdf_filename}.")

def main():
    root = tk.Tk()
    root.title("DMARC Record Generator")

    global domain, rua, pct, policy, ruf

    input_fields = [
        ("Domain:", "example.com"),
        ("Reporting URI for Aggregate reports:", "[email protected]"),
        ("Percentage of messages subjected to filtering (0-100):", "100"),
        ("Policy for handling failed messages:", "none"),
        ("Reporting URI for Forensic reports:", "[email protected]")
    ]

    entries = {}
    for label_text, default_value in input_fields:
        label = tk.Label(root, text=label_text)
        label.pack()
        entry_var = tk.StringVar(value=default_value)
        entry = tk.Entry(root, textvariable=entry_var)
        entry.pack()
        if label_text == "Domain:":
            domain = entry_var
        elif label_text == "Reporting URI for Aggregate reports:":
            rua = entry_var
        elif label_text == "Percentage of messages subjected to filtering (0-100):":
            pct = entry_var
        elif label_text == "Policy for handling failed messages:":
            policy = entry_var
        elif label_text == "Reporting URI for Forensic reports:":
            ruf = entry_var
        entries[label_text] = entry

    generate_button = tk.Button(root, text="Generate DMARC Record", command=generate_dmarc_record)
    generate_button.pack()

    root.mainloop()

if __name__ == "__main__":
    main()

Running the Application

To run the application, execute the Python script. A GUI window will appear where you can enter the domain, RUA, PCT, policy, and RUF values. Click the "Generate DMARC Record" button, and you will be prompted to save a PDF file with the DMARC record and instructions.

This application simplifies the process of generating DMARC records and provides clear instructions for adding them to a DNS server. It can be a valuable tool for email administrators and organizations looking to enhance their email security.

In summary, we've covered how to create a Python application using Tkinter and ReportLab to generate DMARC records and save them, along with setup instructions, in a PDF document. This can be a useful utility for improving email security and ensuring proper email authentication and reporting.

Feel free to customize and extend this code to suit your specific requirements. It provides a foundation for creating DMARC records and saving them in a user-friendly and shareable format.

Output

DMARC Record generator

DMARC Record for example

Note. The values are just for explanation, do not represent any actual values, and are for understanding purposes only. 


Similar Articles