1
0
flashmob 9 жил өмнө
parent
commit
b3d5c37319
4 өөрчлөгдсөн 103 нэмэгдсэн , 44 устгасан
  1. 8 0
      README.md
  2. 29 29
      goguerrilla.conf.sample
  3. 13 10
      goguerrilla.go
  4. 53 5
      smtpd.go

+ 8 - 0
README.md

@@ -176,11 +176,19 @@ Copy goguerrilla.conf.sample to goguerrilla.conf
             ]
     }
 
+The Json parser is very strict on syntax. If there's a parse error and it
+doesn't give much clue, then test your syntax here:
+http://jsonlint.com/#
 	
 
 Releases
 =========================================================
 
+1.5 - 1st Nov 2016
+- Fixed DoS vulnerability, now server will stop reading after a limit is reached
+- syntax error in Json goguerrilla.conf.sample
+- check database back-end connections before starting
+
 1.4 - 25th Oct 2016
 - New Feature: multiple servers!
 - Changed the configuration file format to support multiple servers,

+ 29 - 29
goguerrilla.conf.sample

@@ -1,5 +1,5 @@
 {
-    "allowed_hosts": "guerrillamail.com,guerrillamailblock.com,sharklasers.com,guerrillamail.net,guerrillamail.org"
+    "allowed_hosts": "guerrillamail.com,guerrillamailblock.com,sharklasers.com,guerrillamail.net,guerrillamail.org",
     "primary_mail_host":"sharklasers.com",
     "verbose":false,
     "mysql_db":"gmail_mail",
@@ -11,32 +11,32 @@
 	"redis_expire_seconds" : 3600,
 	"save_workers_size" : 3,
 	"pid_file" : "/var/run/go-guerrilla.pid",
-    	"servers" : [
-    	    {
-                "is_enabled" : true,
-                "host_name":"mail.test.com",
-                "max_size": 1000000,
-                "private_key_file":"/path/to/pem/file/test.com.key",
-                "public_key_file":"/path/to/pem/file/test.com.crt",
-                "timeout":180,
-                "listen_interface":"127.0.0.1:25",
-                "start_tls_on":true,
-                "tls_always_on":false,
-                "max_clients": 1000,
-                "log_file":"/dev/stdout"
-    	    },
-    	    {
-                "is_enabled" : true,
-                "host_name":"mail.test.com",
-                "max_size":1000000,
-                "private_key_file":"/path/to/pem/file/test.com.key",
-                "public_key_file":"/path/to/pem/file/test.com.crt",
-                "timeout":180,
-                "listen_interface":"127.0.0.1:465",
-                "start_tls_on":false,
-                "tls_always_on":true,
-                "max_clients":500,
-                "log_file":"/dev/stdout"
-            }
-    	]
+    "servers" : [
+        {
+            "is_enabled" : true,
+            "host_name":"mail.test.com",
+            "max_size": 1000000,
+            "private_key_file":"/path/to/pem/file/test.com.key",
+            "public_key_file":"/path/to/pem/file/test.com.crt",
+            "timeout":180,
+            "listen_interface":"127.0.0.1:25",
+            "start_tls_on":true,
+            "tls_always_on":false,
+            "max_clients": 1000,
+            "log_file":"/dev/stdout"
+        },
+        {
+            "is_enabled" : true,
+            "host_name":"mail.test.com",
+            "max_size":1000000,
+            "private_key_file":"/path/to/pem/file/test.com.key",
+            "public_key_file":"/path/to/pem/file/test.com.crt",
+            "timeout":180,
+            "listen_interface":"127.0.0.1:465",
+            "start_tls_on":false,
+            "tls_always_on":true,
+            "max_clients":500,
+            "log_file":"/dev/stdout"
+        }
+    ]
 }

+ 13 - 10
goguerrilla.go

@@ -71,16 +71,19 @@ func runServer(sConfig ServerConfig) {
 	server.openLog()
 
 	// configure ssl
-	cert, err := tls.LoadX509KeyPair(sConfig.Public_key_file, sConfig.Private_key_file)
-	if err != nil {
-		server.logln(2, fmt.Sprintf("There was a problem with loading the certificate: %s", err))
-	}
-	server.tlsConfig = &tls.Config{
-		Certificates: []tls.Certificate{cert},
-		ClientAuth:   tls.VerifyClientCertIfGiven,
-		ServerName:   sConfig.Host_name,
+	if (sConfig.Tls_always_on || sConfig.Start_tls_on) {
+		cert, err := tls.LoadX509KeyPair(sConfig.Public_key_file, sConfig.Private_key_file)
+		if err != nil {
+			server.logln(2, fmt.Sprintf("There was a problem with loading the certificate: %s", err))
+		}
+		server.tlsConfig = &tls.Config{
+			Certificates: []tls.Certificate{cert},
+			ClientAuth:   tls.VerifyClientCertIfGiven,
+			ServerName:   sConfig.Host_name,
+		}
+		server.tlsConfig.Rand = rand.Reader
 	}
-	server.tlsConfig.Rand = rand.Reader
+
 
 	// configure timeout
 	server.timeout = time.Duration(sConfig.Timeout)
@@ -106,7 +109,7 @@ func runServer(sConfig ServerConfig) {
 			conn:        conn,
 			address:     conn.RemoteAddr().String(),
 			time:        time.Now().Unix(),
-			bufin:       bufio.NewReader(conn),
+			bufin:       newSmtpBufferedReader(conn),
 			bufout:      bufio.NewWriter(conn),
 			clientId:    clientId,
 			savedNotify: make(chan int),

+ 53 - 5
smtpd.go

@@ -20,7 +20,6 @@ type Client struct {
 	helo        string
 	mail_from   string
 	rcpt_to     string
-	read_buffer string
 	response    string
 	address     string
 	data        string
@@ -84,9 +83,10 @@ func (server *SmtpdServer) upgradeToTls(client *Client) bool {
 	err := tlsConn.Handshake() // not necessary to call here, but might as well
 	if err == nil {
 		client.conn = net.Conn(tlsConn)
-		client.bufin = bufio.NewReader(client.conn)
+		client.bufin = newSmtpBufferedReader(client.conn)
 		client.bufout = bufio.NewWriter(client.conn)
 		client.tls_on = true
+
 		return true
 	} else {
 		server.logln(1, fmt.Sprintf("Could not TLS handshake:%v", err))
@@ -251,7 +251,7 @@ func (server *SmtpdServer) handleClient(client *Client) {
 func responseAdd(client *Client, line string) {
 	client.response = line + "\r\n"
 }
-func (server SmtpdServer) closeClient(client *Client) {
+func (server *SmtpdServer) closeClient(client *Client) {
 	client.conn.Close()
 	<-server.sem // Done; enable next client to run.
 }
@@ -259,7 +259,55 @@ func killClient(client *Client) {
 	client.kill_time = time.Now().Unix()
 }
 
-func (server SmtpdServer) readSmtp(client *Client) (input string, err error) {
+type mutableLimitedReader struct {
+	R io.LimitedReader
+}
+
+func (mlr *mutableLimitedReader) setLimit(n int64) {
+	mlr.R.N = n;
+}
+
+func (mlr *mutableLimitedReader) Read(p []byte) (n int, err error) {
+	n, err = mlr.R.Read(p)
+	return
+}
+
+
+
+func newMutableLimitedReader(r io.Reader, n int64) mutableLimitedReader {
+	lr := io.LimitedReader{R:r, N:n}
+	return mutableLimitedReader{lr}
+}
+
+type smtpBufferedReader struct {
+	mlr mutableLimitedReader
+}
+
+func (sbr *smtpBufferedReader) Read(p []byte) (n int, err error) {
+	n, err = sbr.mlr.Read(p)
+	return
+}
+
+func (sbr *smtpBufferedReader) setLimit(n int64) {
+	sbr.mlr.setLimit(n);
+}
+
+func newSmtpBufferedReader(rd io.Reader) *bufio.Reader {
+	mlr := newMutableLimitedReader(rd, 20);
+	z := &smtpBufferedReader{mlr}
+	return bufio.NewReader(z)
+}
+
+/*
+func newSmtpBufferedReader(rd io.Reader) *bufio.Reader {
+	mlr := newMutableLimitedReader(rd, 1024);
+	return bufio.NewReader(mlr)
+}
+*/
+
+
+
+func (server *SmtpdServer) readSmtp(client *Client) (input string, err error) {
 	var reply string
 	// Command state terminator by default
 	suffix := "\r\n"
@@ -309,7 +357,7 @@ func scanSubject(client *Client, reply string) {
 	}
 }
 
-func (server SmtpdServer) responseWrite(client *Client) (err error) {
+func (server *SmtpdServer) responseWrite(client *Client) (err error) {
 	var size int
 	client.conn.SetDeadline(time.Now().Add(server.timeout * time.Second))
 	size, err = client.bufout.WriteString(client.response)