mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-31 01:19:11 +00:00 
			
		
		
		
	Use local MTA for sending e-mail
This commit is contained in:
		| @@ -115,11 +115,10 @@ class SessionResource(object): | |||||||
|                 ), |                 ), | ||||||
|                 common_name = authority.ca_cert.subject.get_attributes_for_oid( |                 common_name = authority.ca_cert.subject.get_attributes_for_oid( | ||||||
|                     NameOID.COMMON_NAME)[0].value, |                     NameOID.COMMON_NAME)[0].value, | ||||||
|                 outbox = dict( |                 mailer = dict( | ||||||
|                     server = config.OUTBOX, |                     name = config.MAILER_NAME, | ||||||
|                     name = config.OUTBOX_NAME, |                     address = config.MAILER_ADDRESS | ||||||
|                     mail = config.OUTBOX_MAIL |                 ) if config.MAILER_ADDRESS else None, | ||||||
|                 ), |  | ||||||
|                 machine_enrollment_allowed=config.MACHINE_ENROLLMENT_ALLOWED, |                 machine_enrollment_allowed=config.MACHINE_ENROLLMENT_ALLOWED, | ||||||
|                 user_enrollment_allowed=config.USER_ENROLLMENT_ALLOWED, |                 user_enrollment_allowed=config.USER_ENROLLMENT_ALLOWED, | ||||||
|                 user_multiple_certificates=config.USER_MULTIPLE_CERTIFICATES, |                 user_multiple_certificates=config.USER_MULTIPLE_CERTIFICATES, | ||||||
|   | |||||||
| @@ -1313,6 +1313,16 @@ def certidude_setup_yubikey(authority, slot, username, pin): | |||||||
|     subprocess.call(cmd) |     subprocess.call(cmd) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @click.command("test", help="Test mailer") | ||||||
|  | @click.argument("recipient") | ||||||
|  | def certidude_test(recipient): | ||||||
|  |     from certidude import mailer | ||||||
|  |     mailer.send( | ||||||
|  |         "test.md", | ||||||
|  |         to=recipient | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @click.group("strongswan", help="strongSwan helpers") | @click.group("strongswan", help="strongSwan helpers") | ||||||
| def certidude_setup_strongswan(): pass | def certidude_setup_strongswan(): pass | ||||||
|  |  | ||||||
| @@ -1344,6 +1354,7 @@ entry_point.add_command(certidude_revoke) | |||||||
| entry_point.add_command(certidude_list) | entry_point.add_command(certidude_list) | ||||||
| entry_point.add_command(certidude_users) | entry_point.add_command(certidude_users) | ||||||
| entry_point.add_command(certidude_cron) | entry_point.add_command(certidude_cron) | ||||||
|  | entry_point.add_command(certidude_test) | ||||||
|  |  | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     entry_point() |     entry_point() | ||||||
|   | |||||||
| @@ -41,9 +41,8 @@ SIGNED_DIR = cp.get("authority", "signed dir") | |||||||
| REVOKED_DIR = cp.get("authority", "revoked dir") | REVOKED_DIR = cp.get("authority", "revoked dir") | ||||||
| EXPIRED_DIR = cp.get("authority", "expired dir") | EXPIRED_DIR = cp.get("authority", "expired dir") | ||||||
|  |  | ||||||
| OUTBOX = cp.get("authority", "outbox uri") | MAILER_NAME = cp.get("mailer", "name") | ||||||
| OUTBOX_NAME = cp.get("authority", "outbox sender name") | MAILER_ADDRESS = cp.get("mailer", "address") | ||||||
| OUTBOX_MAIL = cp.get("authority", "outbox sender address") |  | ||||||
|  |  | ||||||
| BUNDLE_FORMAT = cp.get("bundle", "format") | BUNDLE_FORMAT = cp.get("bundle", "format") | ||||||
| OPENVPN_PROFILE_TEMPLATE = cp.get("bundle", "openvpn profile template") | OPENVPN_PROFILE_TEMPLATE = cp.get("bundle", "openvpn profile template") | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ env = Environment(loader=PackageLoader("certidude", "templates/mail")) | |||||||
|  |  | ||||||
| def send(template, to=None, attachments=(), **context): | def send(template, to=None, attachments=(), **context): | ||||||
|     from certidude import authority, config |     from certidude import authority, config | ||||||
|     if not config.OUTBOX: |     if not config.MAILER_ADDRESS: | ||||||
|         # Mailbox disabled, don't send e-mail |         # Mailbox disabled, don't send e-mail | ||||||
|         return |         return | ||||||
|  |  | ||||||
| @@ -25,52 +25,12 @@ def send(template, to=None, attachments=(), **context): | |||||||
|  |  | ||||||
|     click.echo("Sending e-mail %s to %s" % (template, recipients)) |     click.echo("Sending e-mail %s to %s" % (template, recipients)) | ||||||
|  |  | ||||||
|     scheme, netloc, path, params, query, fragment = urlparse(config.OUTBOX) |  | ||||||
|     scheme = scheme.lower() |  | ||||||
|  |  | ||||||
|     if path: |  | ||||||
|         raise ValueError("Path for URL not supported") |  | ||||||
|     if params: |  | ||||||
|         raise ValueError("Parameters for URL not supported") |  | ||||||
|     if query: |  | ||||||
|         raise ValueError("Query for URL not supported") |  | ||||||
|     if fragment: |  | ||||||
|         raise ValueError("Fragment for URL not supported") |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     username = None |  | ||||||
|     password = "" |  | ||||||
|  |  | ||||||
|     if scheme == "smtp": |  | ||||||
|         secure = False |  | ||||||
|         port = 25 |  | ||||||
|     elif scheme == "smtps": |  | ||||||
|         secure = True |  | ||||||
|         port = 465 |  | ||||||
|     else: |  | ||||||
|         raise ValueError("Unknown scheme '%s', currently SMTP and SMTPS are only supported" % scheme) |  | ||||||
|  |  | ||||||
|     if "@" in netloc: |  | ||||||
|         credentials, netloc = netloc.split("@") |  | ||||||
|  |  | ||||||
|         if ":" in credentials: |  | ||||||
|             username, password = credentials.split(":") |  | ||||||
|         else: |  | ||||||
|             username = credentials |  | ||||||
|  |  | ||||||
|     if ":" in netloc: |  | ||||||
|         server, port_str = netloc.split(":") |  | ||||||
|         port = int(port_str) |  | ||||||
|     else: |  | ||||||
|         server = netloc |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     subject, text = env.get_template(template).render(context).split("\n\n", 1) |     subject, text = env.get_template(template).render(context).split("\n\n", 1) | ||||||
|     html = markdown(text) |     html = markdown(text) | ||||||
|  |  | ||||||
|     msg = MIMEMultipart("alternative") |     msg = MIMEMultipart("alternative") | ||||||
|     msg["Subject"] = subject |     msg["Subject"] = subject | ||||||
|     msg["From"] = "%s <%s>" % (config.OUTBOX_NAME, config.OUTBOX_MAIL) |     msg["From"] = "%s <%s>" % (config.MAILER_NAME, config.MAILER_ADDRESS) | ||||||
|     msg["To"] = recipients |     msg["To"] = recipients | ||||||
|  |  | ||||||
|     part1 = MIMEText(text, "plain") |     part1 = MIMEText(text, "plain") | ||||||
| @@ -85,12 +45,5 @@ def send(template, to=None, attachments=(), **context): | |||||||
|         part.set_payload(attachment) |         part.set_payload(attachment) | ||||||
|         msg.attach(part) |         msg.attach(part) | ||||||
|  |  | ||||||
|     # Gmail employs some sort of IPS |     conn = smtplib.SMTP("localhost") | ||||||
|     # https://accounts.google.com/DisplayUnlockCaptcha |     conn.sendmail(config.MAILER_ADDRESS, recipients, msg.as_string()) | ||||||
|     conn = smtplib.SMTP(server, port) |  | ||||||
|     if secure: |  | ||||||
|         conn.starttls() |  | ||||||
|     if username and password: |  | ||||||
|         conn.login(username, password) |  | ||||||
|  |  | ||||||
|     conn.sendmail(config.OUTBOX_MAIL, recipients, msg.as_string()) |  | ||||||
|   | |||||||
| @@ -18,9 +18,8 @@ as such require complete reset of X509 infrastructure if some of them needs to b | |||||||
|  |  | ||||||
| <p>These can be reconfigured via /etc/certidude/server.conf on the server.</p> | <p>These can be reconfigured via /etc/certidude/server.conf on the server.</p> | ||||||
|  |  | ||||||
| {% if session.authority.outbox %} | {% if session.authority.mailer %} | ||||||
|     <p>Outgoing mail server: {{ session.authority.outbox.server }}</p> |     <p>Mails will appear from: {{ session.authority.mailer.name }} <{{ session.authority.mailer.address }}></p> | ||||||
|     <p>Mails will appear from: {{ session.authority.outbox.name }} <{{ session.authority.outbox.mail }}></p> |  | ||||||
| {% else %} | {% else %} | ||||||
|     <p>E-mail disabled</p> |     <p>E-mail disabled</p> | ||||||
| {% endif %} | {% endif %} | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								certidude/templates/mail/test.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								certidude/templates/mail/test.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | Test mail | ||||||
|  |  | ||||||
|  | Testing! | ||||||
| @@ -131,10 +131,15 @@ signed dir = {{ directory }}/signed/ | |||||||
| revoked dir = {{ directory }}/revoked/ | revoked dir = {{ directory }}/revoked/ | ||||||
| expired dir = {{ directory }}/expired/ | expired dir = {{ directory }}/expired/ | ||||||
|  |  | ||||||
| outbox uri = | [mailer] | ||||||
| ;outbox uri = {{ outbox }} | # Certidude submits mails to local MTA. | ||||||
| outbox sender name = Certificate management | # In case of Postfix configure it as "Sattelite system", | ||||||
| outbox sender address = certificates@example.com | # and make sure Certidude machine doesn't try to accept mails. | ||||||
|  | # uncomment mail sender address to enable e-mails. | ||||||
|  | # Make sure used e-mail address is reachable for end users. | ||||||
|  | name = Certificate management | ||||||
|  | address = | ||||||
|  | ;address = certificates@example.com | ||||||
|  |  | ||||||
| [bundle] | [bundle] | ||||||
| format = p12 | format = p12 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user