check_ssl_certificate - Support for ManageSieve/STARTTLS
This commit is contained in:
parent
65239769a0
commit
5badf33e31
1 changed files with 52 additions and 3 deletions
|
@ -1,8 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
|
@ -38,7 +40,7 @@ func (f fullTLSGetter) getCertificate(tlsConfig *tls.Config, address string) (*x
|
||||||
return conn.ConnectionState().PeerCertificates[0], nil
|
return conn.ConnectionState().PeerCertificates[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMTP STARTTLS getter
|
// SMTP+STARTTLS certificate getter
|
||||||
type smtpGetter struct{}
|
type smtpGetter struct{}
|
||||||
|
|
||||||
func (f smtpGetter) cmd(tcon *textproto.Conn, expectCode int, text string) (int, string, error) {
|
func (f smtpGetter) cmd(tcon *textproto.Conn, expectCode int, text string) (int, string, error) {
|
||||||
|
@ -74,10 +76,57 @@ func (f smtpGetter) getCertificate(tlsConfig *tls.Config, address string) (*x509
|
||||||
return t.ConnectionState().PeerCertificates[0], nil
|
return t.ConnectionState().PeerCertificates[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ManageSieve STARTTLS certificate getter
|
||||||
|
type sieveGetter struct{}
|
||||||
|
|
||||||
|
func (f sieveGetter) waitOK(conn net.Conn) error {
|
||||||
|
scanner := bufio.NewScanner(conn)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.HasPrefix(line, "OK") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "NO ") {
|
||||||
|
return errors.New(line[3:])
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(line, "BYE ") {
|
||||||
|
return errors.New(line[4:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scanner.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f sieveGetter) runCmd(conn net.Conn, cmd string) error {
|
||||||
|
if _, err := fmt.Fprintf(conn, "%s\r\n", cmd); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return f.waitOK(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f sieveGetter) getCertificate(tlsConfig *tls.Config, address string) (*x509.Certificate, error) {
|
||||||
|
conn, err := net.Dial("tcp", address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
if err := f.waitOK(conn); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := f.runCmd(conn, "STARTTLS"); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
t := tls.Client(conn, tlsConfig)
|
||||||
|
if err := t.Handshake(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return t.ConnectionState().PeerCertificates[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
// Supported StartTLS protocols
|
// Supported StartTLS protocols
|
||||||
var certGetters map[string]certGetter = map[string]certGetter{
|
var certGetters map[string]certGetter = map[string]certGetter{
|
||||||
"": fullTLSGetter{},
|
"": fullTLSGetter{},
|
||||||
"smtp": &smtpGetter{},
|
"smtp": &smtpGetter{},
|
||||||
|
"sieve": &sieveGetter{},
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue