flashmob / go-guerrilla Goto Github PK
View Code? Open in Web Editor NEWMini SMTP server written in golang
License: MIT License
Mini SMTP server written in golang
License: MIT License
Hello and thanks for the great software. I am trying to set this up on a server but am unsure on how to actually make emails sent be received. I'm assuming I need to set up DNS but have no experience with setting up email server DNS. It would be helpful if the documentation or wiki had a section for setting up the domain / DNS.
Apologies for the naive question. I am currently investigating different SMTP servers for receiving email and this one caught my attention (wanting to build that project in Go).
I seem to have problems figuring out how to get started with this project.
To build, just run
$ go build
(...)
This information is a little bit unclear. Running build from the root doesn't seem to do much. How were I to go specifically from checking this project out to actually running it?
Any hint in the right direction would be greatly appreciated!
SMTP spec uses dot stuffing when reading in after the DATA command. However, the current server implements it incorrectly where it doesn't remove a dot if a line with text starts with a dot.
To fix:
Will switch to using go's standard package textproto, using the DotReader.
Additionally, this is an opportunity to change Envelope.Data to a bytes.Buffer, so that the buffer can be re-used after it is placed back in the pool.
The textproto package could also be used for header parsing too.
Hi, How can i tell the package to stop outputting ?
When importing as a package in an application already using logrus upon compilation it returns the following error:
src/github.com/flashmob/go-guerrilla/log/hook.go:5:2: case-insensitive import collision: "github.com/Sirupsen/logrus" and "github.com/sirupsen/logrus"
The current logrus readme reports the change in case for the github user asking the update of the package name whenever used to match the new lowercase one.
Could you please update?
Why does Backend has private methods?
go-guerrilla/backends/backend.go
Line 20 in 9d9d864
The readme file mentions that different backends can be implemented but it doesn't seem to be the case because you can't use unexported types. It is misleading at best for several reasons:
c *envelope.Envelope
not c *guerrilla.Envelope
. type BackendResult is located in the backends package so it should be backends.BackendResult
not guerrilla.BackendResult
type CustomBackend struct {...}
func (cb *CustomBackend) Process(c *guerrilla.Envelope) guerrilla.BackendResult {
err := saveSomewhere(c.Data)
if err != nil {
return guerrilla.NewBackendResult(fmt.Sprintf("554 Error: %s", err.Error()))
}
return guerrilla.NewBackendResult("250 OK")
}
An exported interface with private methods makes no sense, does it?
@jordanschalm has started working on Analytics package
https://github.com/flashmob/go-guerrilla/tree/dashboard
We have agreed that we will drop the TLS & password protection requirement, since we do not have Lets Encrypt automation yet, and self signed certs can be MITM'd. So bind to localhost for now.
The way it may be implemented is via the existing logging facility. A goroutine will log take samples periodically and write them to the log. Another goroutine can tail the log and ready the data for presentation.
(Note that in the future, the log could be closed and reopened upon a SIGHUP signal)
Presentation data will be rendered using vanilla Js and a js charting library.
Hi, good day, I'd like ask you if it's possible send the incoming emails to our api, for instance, catch the subject, sender and body and send to some api rest through http...thank you!!
Currently Mails are being rejected, if the MAIL FROM is empty (e.g. MAIL FROM:<>).
This is technically allowed according to RfC 5321 and designates a bounce message.
Even though proxying via Nginx is not necessary these days, proxy support may still be useful for load balancing purposes.
The proxy server uses the XCLIENT command to tell the server behind the proxy what the source IP address is.
Requirements:
Support the XCLIENT command (with an option to enable it in config).
case strings.Index(cmd, "XCLIENT") == 0:
// Nginx sends this
// XCLIENT ADDR=212.96.64.216 NAME=[UNAVAILABLE]
client.Address = input[13:]
client.Address = client.Address[0:strings.Index(client.Address, " ")]
fmt.Println("client address:[" + client.Address + "]")
responseAdd(client, "250 OK")
In order to write unit tests, I want to extract storing mechanism (save_mail.go
) from the code and move it into a package. Would you accept such refactoring? Are you ok with this layouting? Thanks :)
Unlimited number of recipients can be added to the client.RcptTo slice by repeating the RCPT TO command. This could lead to a DOS attack causing memory exhaustion.
This affects only the release candidate in master.
To do:
Limit the number to 100 max.
Additionally, RCPT TO and MAIL FROM should be checked for lengths too
I'm looking to implement LetsEncrypt but I've got stuck on basic understanding of the code due the lack of documentation. What is AppConfig.AllowedHosts
and how is it related to ServerConfig.Hostname
?
The Prometheus stack (Prometheus + Grafana) can be used to provide slick, powerful and flexible dashboards. All the project needs to do is to export metrics through an endpoint (e.g., /metrics
) and let Prometheus scrape it. Prometheus has a powerful data model and query language (PromQL).
Can I fork, modify and run on my systems?
Some web mail client [SOGo] send the subject starting with ?utf-8?q?the subject....
Shall it be decoded within go-guerrilla?
Hello,
I'm attempting to use the guerrilla-db-redis backend. I've populated my mysql DB with the SQL provided in README.md but I still get the following error.
[root@Meteor go-guerrilla]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 53
Server version: 5.5.52-MariaDB MariaDB Server
Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> use gmail
Database changed
MariaDB [gmail]> CREATE TABLE IF NOT EXISTS `new_mail` ( `mail_id` int(11) NOT NULL auto_increment, `date` datetime NOT NULL, `from` varchar(128) character set latin1 NOT NULL, `to` varchar(128) character set latin1 NOT NULL, `subject` varchar(255) NOT NULL, `body` text NOT NULL, `charset` varchar(32) character set latin1 NOT NULL, `mail` longblob NOT NULL, `spam_score` float NOT NULL, `hash` char(32) character set latin1 NOT NULL, `content_type` varchar(64) character set latin1 NOT NULL, `recipient` varchar(128) character set latin1 NOT NULL, `has_attach` int(11) NOT NULL, `ip_addr` varchar(15) NOT NULL, `delivered` bit(1) NOT NULL default b'0', `attach_info` text NOT NULL, `dkim_valid` tinyint(4) default NULL, PRIMARY KEY (`mail_id`), KEY `to` (`to`), KEY `hash` (`hash`), KEY `date` (`date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)
MariaDB [gmail]> Bye
[root@Meteor go-guerrilla]# ./guerrillad -v serve
INFO[0000] guerrillad 1.5.1-30-g44d8a9d
DEBU[0000] Build Time: 2017-01-20_01:28:15_-0500
DEBU[0000] Commit: 44d8a9dc97cd149d7cbce80a293dda9ff248ea97
DEBU[0000] making servers
INFO[0000] Listening on TCP 0.0.0.0:25
DEBU[0000] [0.0.0.0:25] Waiting for a new client. Next Client ID: 1
INFO[0000] pid_file (/var/run/go-guerrilla.pid) written with pid:6849
FATA[0000] failed while db.Prepare(INSERT...) error="Received #1054 error from MySQL server: \"Unknown column 'return_path' in 'field list'\""
Shouldn't the schema be 1:1 not 15 of 17? (sorry for the poor illustration!):
[root@Meteor go-guerrilla]# mysql gmail -Ne 'desc new_mail' | nl
1 mail_id int(11) NO PRI NULL auto_increment
2 date datetime NO MUL NULL
3 from varchar(128) NO NULL
4 to varchar(128) NO MUL NULL
5 subject varchar(255) NO NULL
6 body text NO NULL
7 charset varchar(32) NO NULL
8 mail longblob NO NULL
9 spam_score float NO NULL
10 hash char(32) NO MUL NULL
11 content_type varchar(64) NO NULL
12 recipient varchar(128) NO NULL
13 has_attach int(11) NO NULL
14 ip_addr varchar(15) NO NULL
15 delivered bit(1) NO b'0'
16 attach_info text NO NULL
17 dkim_valid tinyint(4) YES NULL
[root@Meteor go-guerrilla]# git grep return_path | tr , '\n' | nl
1 backends/guerrilla_db_redis.go: sql += "(`date`
2 `to`
3 `from`
4 `subject`
5 `body`
6 `charset`
7 `mail`
8 `spam_score`
9 `hash`
10 `content_type`
11 `recipient`
12 `has_attach`
13 `ip_addr`
14 `return_path`
15 `is_tls`)"
Some clients are refusing to connect over SSL due to either v2 not being supported, or v3 not agreeing a cipher. Is there some config change required to allow other ciphers, or is nginx still required to handle STARTTLS connections?
https://blog.gopheracademy.com/advent-2016/exposing-go-on-the-internet/
Requirements:
Ability to set the modern TLS config via the json file config. (For each server).
Sample json config to contain settings as recommended on above blog
RFC https://tools.ietf.org/html/rfc3463
https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xml
Implement enhanced status codes to all status messages
Advertise 250-ENHANCEDSTATUSCODES after EHLO
Automated tests for all codes
Hiya, I used go-guerilla to set up a dummy SMTP server for load testing our senders and I'd like to pay back the favor by increasing test coverage.
Curious about priority packages and testing conventions. Thanks!
What solution would you use/propose for sending email ? (I understand that go-guerrilla is only for receiving emails).
I would like to adapt go-guerrilla to build my own webmail. Wouldn't be ok for the local smtp client to talk to this server?
thanks
Hello.
When you executes guerrillad server as root the run with 0 uid (root uid).
I propose you to add priviledge separation using something function similar to https://golang.org/pkg/os/#StartProcess
You can read about github.com/sevlyar/go-daemon using daemons and handling processes in background with gouroutine functionality.
Thank you!
Hi there,
I had to run this to get go-guerrilla to run:
CREATE TABLE gm2_setting
(
setting_name VARCHAR(128),
setting_value INT NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Maybe it should be included in the README.
Is there a way to stream "DATA command" payload. Looking at the code it seems data is kept in memory buffer and then passed it on to the backend processor.
While keeping data in memory gives you better performance. This could be a problem if you have too many connections or large payloads.
Any suggestions?
Thanks.
It would be cool if instead of using a mix of redis/mysql it would use a queue (rabbit/beanstalkd/maybe even sqs) to push new messages into (might not work with large attachments though).
That way the implementation of what is being done with a email is fully seperated from the mx.
How about adding a new 'signal' command to ./guerrillad
To reload config
guerrillad signal reload
For graceful shutdown
guerrillad signal quit
To implement it, assuming that we can write syscall.SIGHUP and syscall.SIGTERM to the signalChannel channel declared in serve.go
the BackendGateway will always return FailBackendTransaction (554) if there is an error in one of the backend processors.
It would be useful if the error specified from the processor would be parsed and returned if valid...similar to this:
// wait for the save to complete
// or timeout
select {
case status := <-workerMsg.notifyMe:
defer workerMsgPool.Put(workerMsg) // can be recycled since we used the notifyMe channel
if status.err != nil {
if _, err := strconv.Atoi(status.err.Error()[:3]); err != nil {
return NewResult(response.Canned.FailBackendTransaction + status.err.Error())
}
return NewResult(status.err.Error())
}
return NewResult(response.Canned.SuccessMessageQueued + status.queuedID)
case <-time.After(gw.saveTimeout()):
Log().Error("Backend has timed out while saving eamil")
return NewResult(response.Canned.FailBackendTimeout)
}
in this way the backend could respond 421 (for example) and allow the client to retry to send the email.
Another solution could be to add the backend result in the notifyMsg
(or a pointer to it)
Already have a fix - this issue is just to track the fix
ssl_protocols SSLv2 SSLv3 TLSv1;
SSLv2 doesn't exist anymore, and sslv3 is rotten.
Example:
Send email from anywhere to guerrillamail with the following text:
123456789012345678901234567890123456789012345678901234567890123456789012345.com
Result in Show original
:
123456789012345678901234567890123456789012345678901234567890123456789012345=
..com
guerrillamail duplicates the dot.
This causes links to be broken.
Good luck :)
Let’s Encrypt and the golang.org/x/crypto/acme/autocert package’s GetCertificate function.
Requirements:
./guerrillad certificate <server-interface> new
to issue a new cert & add to config. (using the primary_mail_host as as the FQDN
./guerrillad certificate <server-interface> renew
to renew
./guerrillad certificate renew
to renew all certificates
I needed go-qprintable for this to compile, which was missing in the getting started section of README.
eparra@eparra:/go$ go get github.com/ziutek/mymysql/thrsafe/go$ go get github.com/ziutek/mymysql/autorc
eparra@eparra:
eparra@eparra:/go$ go get github.com/ziutek/mymysql/godrv/go$ go get github.com/sloonz/go-iconv
eparra@eparra:
eparra@eparra:/go$ go get github.com/garyburd/redigo/redis/go$ go build go-guerrilla.go
eparra@eparra:
go-guerrilla.go:72:2: cannot find package "github.com/sloonz/go-qprintable" in any of:
/usr/local/go/src/github.com/sloonz/go-qprintable (from $GOROOT)
/Users/eparra/go/src/github.com/sloonz/go-qprintable (from $GOPATH)
eparra@eparra:/go$ go get github.com/sloonz/go-qprintable/go$ go build go-guerrilla.go
eparra@eparra:
If loading the certificate fails, we must not advertise STARTTLS nor we should open an TLS-only host.
A check is to be implemented, if the configured certificate is existing and maybe even a check if it is valid.
It looks like redis is used to save data in the channel as it comes in but I don't see anywhere where the data is being read and it seems the data is actually saved to MySQL ultimately too.
What is redis doing?
Hello, interested in contributing to this project as I believe it will be very useful for a personal project I have in mind. Is implementing a client pool still one of the contributions you are looking for?
Hello,
In mysql i'm logging all the same IP addresses. Upon further investigation, I see the wrong remote_address being shown in console (verbose) output as well.
It appears the first received email (expected test emails from my web server) remote address is used for all subsequent incoming mail.
Here's my evidence/findings so far.. (addresses obfuscated)
Console output:
INFO[14028] Handle client [<myWebServer>:50219], id: 2
DEBU[14028] Writing response to client:
220 mx.mydomain.com SMTP Guerrilla(1.5.1-30-g44d8a9d) #2 (1) 2017-01-21T09:56:12-05:00 gr:9
DEBU[14028] Client sent: HELO localhost
DEBU[14028] Writing response to client:
250 mx.mydomain.com Hello
DEBU[14028] Client sent: MAIL FROM: <[email protected]>
DEBU[14028] Writing response to client:
250 OK
DEBU[14028] Client sent: RCPT TO: <[email protected]>
DEBU[14028] Writing response to client:
250 OK
DEBU[14029] Client sent: DATA
DEBU[14029] Writing response to client:
354 Enter message, ending with '.' on a line by itself
DEBU[14029] Email saved c769dd047cbc18eb3eb754d22c5bcb3a (len=20080)
DEBU[14029] Writing response to client:
250 OK : queued as c769dd047cbc18eb3eb754d22c5bcb3a
DEBU[14029] Client sent: QUIT
DEBU[14029] Writing response to client:
221 Bye
And that mail is recorded in MySQL as coming from MY Web server IP:
+---------------------+-----------------+
| date | ip_addr |
+---------------------+-----------------+
| 2017-01-20 18:20:53 | <myWebServer>:52 |
| 2017-01-20 18:40:50 | <myWebServer>:58 |
| 2017-01-21 01:34:31 | <myWebServer>:58 |
| 2017-01-21 01:43:22 | <myWebServer>:58 |
| 2017-01-21 01:46:22 | <myWebServer>:58 |
| 2017-01-21 04:44:12 | <myWebServer>:58 |
| 2017-01-21 06:01:08 | <myWebServer>:58 |
| 2017-01-21 06:03:09 | <myWebServer>:50 |
| 2017-01-21 09:56:13 | <myWebServer>:50 |
+---------------------+-----------------+
9 rows in set (0.00 sec)
But myWebServer never sent an email at 09:56:13 and a tcpdump on myGuerrillaMail server proves this:
09:56:12.187568 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [S], seq 3530872155, win 14600, options [mss 1460,sackOK,TS val 13352891 ecr 0,nop,wscale 7], length 0
09:56:12.187610 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [S.], seq 1217573791, ack 3530872156, win 14480, options [mss 1460,sackOK,TS val 2926659315 ecr 13352891,nop,wscale 7],
length 0
09:56:12.332680 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], ack 1, win 115, options [nop,nop,TS val 13352927 ecr 2926659315], length 0
09:56:12.333016 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 1:96, ack 1, win 114, options [nop,nop,TS val 2926659461 ecr 13352927], length 95
09:56:12.477180 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], ack 96, win 115, options [nop,nop,TS val 13352964 ecr 2926659461], length 0
09:56:12.496068 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 1:17, ack 96, win 115, options [nop,nop,TS val 13352968 ecr 2926659461], length 16
09:56:12.496083 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 17, win 114, options [nop,nop,TS val 2926659624 ecr 13352968], length 0
09:56:12.496227 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 96:125, ack 17, win 114, options [nop,nop,TS val 2926659624 ecr 13352968], length 29
09:56:12.663587 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 17:46, ack 125, win 115, options [nop,nop,TS val 13353010 ecr 2926659624], length 29
09:56:12.663781 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 125:133, ack 46, win 114, options [nop,nop,TS val 2926659792 ecr 13353010], length 8
09:56:12.834716 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 46:84, ack 133, win 115, options [nop,nop,TS val 13353053 ecr 2926659792], length 38
09:56:12.834911 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 133:141, ack 84, win 114, options [nop,nop,TS val 2926659962 ecr 13353053], length 8
09:56:12.992272 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 84:90, ack 141, win 115, options [nop,nop,TS val 13353092 ecr 2926659962], length 6
09:56:12.992404 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 141:197, ack 90, win 114, options [nop,nop,TS val 2926660120 ecr 13353092], length 56
09:56:13.150204 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 90:1538, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150213 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 1538:2986, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150238 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 2986, win 159, options [nop,nop,TS val 2926660278 ecr 13353132], length 0
09:56:13.150254 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 2986:4434, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150261 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 4434:5882, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150282 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 5882, win 204, options [nop,nop,TS val 2926660278 ecr 13353132], length 0
09:56:13.150268 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 5882:7330, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150297 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 7330:8778, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150302 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 8778, win 249, options [nop,nop,TS val 2926660278 ecr 13353132], length 0
09:56:13.150358 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 8778:10226, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150365 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 10226:11674, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150380 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 11674, win 295, options [nop,nop,TS val 2926660278 ecr 13353132], length 0
09:56:13.150372 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 11674:13122, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150422 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 13122:14570, ack 197, win 115, options [nop,nop,TS val 13353132 ecr 2926660120], length 1448
09:56:13.150427 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 14570, win 340, options [nop,nop,TS val 2926660278 ecr 13353132], length 0
09:56:13.294485 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 14570:16018, ack 197, win 115, options [nop,nop,TS val 13353168 ecr 2926660278], length 1448
09:56:13.294494 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 16018:17466, ack 197, win 115, options [nop,nop,TS val 13353168 ecr 2926660278], length 1448
09:56:13.294526 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 17466, win 385, options [nop,nop,TS val 2926660422 ecr 13353168], length 0
09:56:13.294552 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 17466:18914, ack 197, win 115, options [nop,nop,TS val 13353168 ecr 2926660278], length 1448
09:56:13.294563 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [.], seq 18914:20362, ack 197, win 115, options [nop,nop,TS val 13353168 ecr 2926660278], length 1448
09:56:13.294585 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 20362, win 430, options [nop,nop,TS val 2926660422 ecr 13353168], length 0
09:56:13.294571 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 20362:20448, ack 197, win 115, options [nop,nop,TS val 13353168 ecr 2926660278], length 86
09:56:13.333669 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 20448, win 430, options [nop,nop,TS val 2926660462 ecr 13353168], length 0
09:56:13.362872 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 197:250, ack 20448, win 430, options [nop,nop,TS val 2926660491 ecr 13353168], length 53
09:56:13.527752 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [P.], seq 20448:20454, ack 250, win 115, options [nop,nop,TS val 13353226 ecr 2926660491], length 6
09:56:13.527774 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 20454, win 430, options [nop,nop,TS val 2926660655 ecr 13353226], length 0
09:56:13.527943 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [P.], seq 250:259, ack 20454, win 430, options [nop,nop,TS val 2926660655 ecr 13353226], length 9
09:56:13.527985 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [F.], seq 259, ack 20454, win 430, options [nop,nop,TS val 2926660656 ecr 13353226], length 0
09:56:13.674598 IP 95.47.x.x.57927 > <myGuerrillaMailServer>.25: Flags [F.], seq 20454, ack 260, win 115, options [nop,nop,TS val 13353263 ecr 2926660655], length 0
09:56:13.674622 IP <myGuerrillaMailServer>.25 > 95.47.x.x.57927: Flags [.], ack 20455, win 430, options [nop,nop,TS val 2926660802 ecr 13353263], length 0
The IP address 95.47.x.x is the remote address I'm expecting to see/log.
There seems to be a lot of buffering structs added. Why are they being used? Was the go defaults for reading from an io.Reader unsafe?
Are you trying to limit the amount read? You could use an io.LimitReader()
:
data, err := ioutil.ReadAll(io.LimitReader(client.conn, 1000000))
I tried to create my own table and I'm missing some data. Where is the table schema that was used with this?
Currently working on it. Hope to have the following features when a SIG_HUP is caught:
That way the server can continue working without disrupting the hundreds of connections it may have open.
Going to implement it using an event based approach using https://github.com/asaskevich/EventBus
The go-fuzz testing left some crashes to invetsigate here
https://github.com/flashmob/go-guerrilla/tree/tests/workdir/crashers
Fuzz testing procedure is described here:
https://github.com/flashmob/go-guerrilla/wiki/Fuzz-testing
Dodo:
Hello, I tried to go get the latest changes but go install is failing.
flashmob/go-guerrilla/event.go:78: cannot use EventBus.New() (type EventBus.Bus) as type *EventBus.EventBus in assignment: need type assertion
I noticed that the package github.com/asaskevich/EventBus has been changed 6 days ago and created a problem with the compilation of go-guerrilla.
asaskevich/EventBus@5666508
What software is complete without an easter egg?
The HELP command would be a great candidate for an easter egg, since this command is mostly unused and disabled on many other servers.
Todo:
HELP command to reply with random one line quotes from the Big Lebowski
https://www.rottentomatoes.com/m/big_lebowski/quotes/
The Dude abides.
There a another great SMTP server in go called https://github.com/le0pard/go-falcon. It supports POP3 in addition to being a SMTP server which does spam and virus checks. Lots of good things could be borrowed including attachment saving/handling.
You left out:
$ go get github.com/sloonz/go-qprintable
In your install instructions. I know this isn't a big deal, just figured worth keeping the documentation up to date. :)
Hi, I'm currently working on a project that will require an SMTP server with API hooks for processing received mail, and it sounds like you'd like this project to support that, given the Modularize
bounty.
I would be interested in doing a code review and implementing a public API for the package, if that's still something you are interested in adding.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.