goguerrilla.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. Go-Guerrilla SMTPd
  3. Version: 1.5
  4. Author: Flashmob, GuerrillaMail.com
  5. Contact: [email protected]
  6. License: MIT
  7. Repository: https://github.com/flashmob/Go-Guerrilla-SMTPd
  8. Site: http://www.guerrillamail.com/
  9. See README for more details
  10. */
  11. package main
  12. import (
  13. "bufio"
  14. "crypto/rand"
  15. "crypto/tls"
  16. "fmt"
  17. "net"
  18. "os"
  19. "os/signal"
  20. "runtime"
  21. "strconv"
  22. "syscall"
  23. "time"
  24. )
  25. var allowedHosts = make(map[string]bool, 15)
  26. var signalChannel = make(chan os.Signal, 1) // for trapping SIG_HUB
  27. func sigHandler() {
  28. for sig := range signalChannel {
  29. if sig == syscall.SIGHUP {
  30. readConfig()
  31. fmt.Print("Reloading Configuration!\n")
  32. } else {
  33. os.Exit(0)
  34. }
  35. }
  36. }
  37. func initialise() {
  38. // database writing workers
  39. SaveMailChan = make(chan *savePayload, mainConfig.Save_workers_size)
  40. // write out our PID
  41. if f, err := os.Create(mainConfig.Pid_file); err == nil {
  42. defer f.Close()
  43. if _, err := f.WriteString(strconv.Itoa(os.Getpid())); err == nil {
  44. f.Sync()
  45. }
  46. }
  47. // handle SIGHUP for reloading the configuration while running
  48. signal.Notify(signalChannel, syscall.SIGHUP)
  49. return
  50. }
  51. func runServer(sConfig ServerConfig) (err error) {
  52. server := SmtpdServer{Config: sConfig, sem: make(chan int, sConfig.Max_clients)}
  53. // setup logging
  54. server.openLog()
  55. // configure ssl
  56. if (sConfig.Tls_always_on || sConfig.Start_tls_on) {
  57. cert, err := tls.LoadX509KeyPair(sConfig.Public_key_file, sConfig.Private_key_file)
  58. if err != nil {
  59. server.logln(2, fmt.Sprintf("There was a problem with loading the certificate: %s", err))
  60. }
  61. server.tlsConfig = &tls.Config{
  62. Certificates: []tls.Certificate{cert},
  63. ClientAuth: tls.VerifyClientCertIfGiven,
  64. ServerName: sConfig.Host_name,
  65. }
  66. server.tlsConfig.Rand = rand.Reader
  67. }
  68. // configure timeout
  69. server.timeout = time.Duration(sConfig.Timeout)
  70. // Start listening for SMTP connections
  71. listener, err := net.Listen("tcp", sConfig.Listen_interface)
  72. if err != nil {
  73. server.logln(2, fmt.Sprintf("Cannot listen on port, %v", err))
  74. return err
  75. } else {
  76. server.logln(1, fmt.Sprintf("Listening on tcp %s", sConfig.Listen_interface))
  77. }
  78. var clientId int64
  79. clientId = 1
  80. for {
  81. conn, err := listener.Accept()
  82. if err != nil {
  83. server.logln(1, fmt.Sprintf("Accept error: %s", err))
  84. continue
  85. }
  86. server.logln(0, fmt.Sprintf(" There are now "+strconv.Itoa(runtime.NumGoroutine())+" serving goroutines"))
  87. server.sem <- 1 // Wait for active queue to drain.
  88. go server.handleClient(&Client{
  89. conn: conn,
  90. address: conn.RemoteAddr().String(),
  91. time: time.Now().Unix(),
  92. bufin: newSmtpBufferedReader(conn),
  93. bufout: bufio.NewWriter(conn),
  94. clientId: clientId,
  95. savedNotify: make(chan int),
  96. })
  97. clientId++
  98. }
  99. }
  100. func main() {
  101. readConfig()
  102. initialise()
  103. if err := testDbConnections(); err != nil {
  104. fmt.Println(err)
  105. os.Exit(1);
  106. }
  107. // start some savemail workers
  108. for i := 0; i < mainConfig.Save_workers_size; i++ {
  109. go saveMail()
  110. }
  111. // run our servers
  112. for serverId := 0; serverId < len(mainConfig.Servers); serverId++ {
  113. if mainConfig.Servers[serverId].Is_enabled {
  114. go runServer(mainConfig.Servers[serverId])
  115. }
  116. }
  117. sigHandler()
  118. }