summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-06-01 18:13:57 -0700
committerShawn O. Pearce <sop@google.com>2009-06-01 18:13:57 -0700
commit219a8eeaa2061f256abd955202a7f36736539993 (patch)
treef8297a21d4f99d86321fb3a0e9dad9e7c0e17c50
parent43c0c4abf10b03a67d199b45260f172f666149a6 (diff)
Block rcpt to addresses not on a whitelist
This way test instances don't send spam emails, but also companies can configure the whitelist to contain only their corporate domain name and potentially avoid distributing emails outside of their corporate firewall. Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--Documentation/config-gerrit.txt10
-rw-r--r--src/main/java/com/google/gerrit/server/GerritServer.java1
-rw-r--r--src/main/java/org/apache/commons/net/smtp/AuthSMTPClient.java47
3 files changed, 58 insertions, 0 deletions
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 60a1ba59e3..0ecf2aa105 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -393,6 +393,16 @@ sendemail.smtpPass::
+
Password for the account named by sendemail.smtpUser.
+sendemail.allowrcpt::
++
+If present, each value adds one entry to the whitelist of email
+addresses that Gerrit can send email to. If set to a complete
+email address, that one address is added to the white list.
+If set to a domain name, any address at that domain can receive
+email from Gerrit.
++
+By default, unset, permitting delivery to any email address.
+
Section sshd
~~~~~~~~~~~~
diff --git a/src/main/java/com/google/gerrit/server/GerritServer.java b/src/main/java/com/google/gerrit/server/GerritServer.java
index 04d137a201..11c185787b 100644
--- a/src/main/java/com/google/gerrit/server/GerritServer.java
+++ b/src/main/java/com/google/gerrit/server/GerritServer.java
@@ -705,6 +705,7 @@ public class GerritServer {
String smtpPass = cfg.getString("sendemail", null, "smtpuserpass");
final AuthSMTPClient client = new AuthSMTPClient("UTF-8");
+ client.setAllowRcpt(cfg.getStringList("sendemail", null, "allowrcpt"));
try {
client.connect(smtpHost, smtpPort);
if (!SMTPReply.isPositiveCompletion(client.getReplyCode())) {
diff --git a/src/main/java/org/apache/commons/net/smtp/AuthSMTPClient.java b/src/main/java/org/apache/commons/net/smtp/AuthSMTPClient.java
index 3237287b9e..9d708234da 100644
--- a/src/main/java/org/apache/commons/net/smtp/AuthSMTPClient.java
+++ b/src/main/java/org/apache/commons/net/smtp/AuthSMTPClient.java
@@ -14,6 +14,8 @@
package org.apache.commons.net.smtp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.spearce.jgit.util.Base64;
import java.io.IOException;
@@ -21,18 +23,63 @@ import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class AuthSMTPClient extends SMTPClient {
+ private static final Logger log =
+ LoggerFactory.getLogger(AuthSMTPClient.class);
+
private String authTypes;
+ private Set<String> allowedRcptTo;
public AuthSMTPClient(final String charset) {
super(charset);
}
+ public void setAllowRcpt(final String[] allowed) {
+ if (allowed != null && allowed.length > 0) {
+ if (allowedRcptTo == null) {
+ allowedRcptTo = new HashSet<String>();
+ }
+ for (final String addr : allowed) {
+ allowedRcptTo.add(addr);
+ }
+ }
+ }
+
+ @Override
+ public int rcpt(final String forwardPath) throws IOException {
+ if (allowRcpt(forwardPath)) {
+ return super.rcpt(forwardPath);
+ } else {
+ log.warn("Not emailing " + forwardPath + " (prohibited by allowrcpt)");
+ return SMTPReply.ACTION_OK;
+ }
+ }
+
+ private boolean allowRcpt(String addr) {
+ if (allowedRcptTo == null) {
+ return true;
+ }
+ if (addr.startsWith("<") && addr.endsWith(">")) {
+ addr = addr.substring(1, addr.length() - 1);
+ }
+ if (allowedRcptTo.contains(addr)) {
+ return true;
+ }
+ final int at = addr.indexOf('@');
+ if (at > 0) {
+ return allowedRcptTo.contains(addr.substring(at))
+ || allowedRcptTo.contains(addr.substring(at + 1));
+ }
+ return false;
+ }
+
@Override
public String[] getReplyStrings() {
return _replyLines.toArray(new String[_replyLines.size()]);