/
starttls.go
115 lines (98 loc) · 2.17 KB
/
starttls.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package heartbleed
import (
"bufio"
"errors"
"net"
"regexp"
"strings"
)
var Services = []string{
"ftp",
"smtp",
"pop3",
"imap",
}
type LineProtoTriple struct {
GreetMatch string
AuthReq string
ResponseMatch string
}
func (proto *LineProtoTriple) do(w *bufio.Writer, r *bufio.Reader) (err error) {
var line string
re := regexp.MustCompile(proto.GreetMatch)
for {
if line, err = r.ReadString('\n'); err != nil {
return
}
line = strings.TrimRight(line, "\r")
if re.MatchString(line) {
break
}
}
if _, err = w.WriteString(proto.AuthReq + "\r\n"); err != nil {
return
}
if err = w.Flush(); err != nil {
return
}
if line, err = r.ReadString('\n'); err != nil {
return
}
line = strings.TrimRight(line, "\r")
re = regexp.MustCompile(proto.ResponseMatch)
if !re.MatchString(line) {
return errors.New("Server does not support STARTTLS (" + strings.TrimSpace(line) + ")")
}
return
}
func starttls_ftp(w *bufio.Writer, r *bufio.Reader) error {
proto := &LineProtoTriple{
GreetMatch: "^220 ",
AuthReq: "AUTH TLS",
ResponseMatch: "^234 ",
}
return proto.do(w, r)
}
func starttls_smtp(w *bufio.Writer, r *bufio.Reader) error {
proto := &LineProtoTriple{
GreetMatch: "^220 ",
AuthReq: "STARTTLS",
ResponseMatch: "^220 ",
}
return proto.do(w, r)
}
func starttls_pop3(w *bufio.Writer, r *bufio.Reader) error {
proto := &LineProtoTriple{
GreetMatch: "^\\+OK ",
AuthReq: "STLS",
ResponseMatch: "^\\+OK ",
}
return proto.do(w, r)
}
func starttls_imap(w *bufio.Writer, r *bufio.Reader) error {
proto := &LineProtoTriple{
GreetMatch: "^\\* ",
AuthReq: "a001 STARTTLS",
ResponseMatch: "^a001 OK ",
}
return proto.do(w, r)
}
func DoStartTLS(conn net.Conn, startType string) (err error) {
r := bufio.NewReader(conn)
w := bufio.NewWriter(conn)
switch strings.ToLower(startType) {
case "ftp":
err = starttls_ftp(w, r)
case "smtp":
err = starttls_smtp(w, r)
case "pop3":
err = starttls_pop3(w, r)
case "imap":
err = starttls_imap(w, r)
case "http":
err = errors.New("You should check the http\"s\" site")
default:
err = errors.New("Unknown service for StartTLS")
}
return
}