git » chasquid » commit f055a34

Do not allow repeated STARTTLS commands

author Alberto Bertogli
2015-10-26 13:40:44 UTC
committer Alberto Bertogli
2015-10-26 13:40:44 UTC
parent 8c22b3beef210c15d3d30669556209fe98c828ec

Do not allow repeated STARTTLS commands

Clients should only be able to do STARTTLS once.

chasquid.go +9 -0
chasquid_test.go +15 -0

diff --git a/chasquid.go b/chasquid.go
index 58782ea..b3da182 100644
--- a/chasquid.go
+++ b/chasquid.go
@@ -157,6 +157,9 @@ type Conn struct {
 	rcpt_to   []string
 	data      []byte
 
+	// Are we using TLS?
+	onTLS bool
+
 	// When we should close this connection, no matter what.
 	deadline time.Time
 
@@ -395,6 +398,10 @@ func (c *Conn) DATA(params string, tr trace.Trace) (code int, msg string) {
 }
 
 func (c *Conn) STARTTLS(params string, tr trace.Trace) (code int, msg string) {
+	if c.onTLS {
+		return 503, "You are already wearing that!"
+	}
+
 	err := c.writeResponse(220, "You experience a strange sense of peace")
 	if err != nil {
 		return 554, fmt.Sprintf("error writing STARTTLS response: %v", err)
@@ -417,6 +424,8 @@ func (c *Conn) STARTTLS(params string, tr trace.Trace) (code int, msg string) {
 	// Reset the envelope; clients must start over after switching to TLS.
 	c.resetEnvelope()
 
+	c.onTLS = true
+
 	// 0 indicates not to send back a reply.
 	return 0, ""
 }
diff --git a/chasquid_test.go b/chasquid_test.go
index d96ae65..80dc18c 100644
--- a/chasquid_test.go
+++ b/chasquid_test.go
@@ -198,6 +198,21 @@ func TestReset(t *testing.T) {
 	}
 }
 
+func TestRepeatedStartTLS(t *testing.T) {
+	c, err := smtp.Dial(srvAddr)
+	if err != nil {
+		t.Fatalf("smtp.Dial: %v", err)
+	}
+
+	if err = c.StartTLS(tlsConfig); err != nil {
+		t.Fatalf("StartTLS: %v", err)
+	}
+
+	if err = c.StartTLS(tlsConfig); err == nil {
+		t.Errorf("Second STARTTLS did not fail as expected")
+	}
+}
+
 //
 // === Benchmarks ===
 //