Skip to content

Commit

Permalink
Merge pull request #2 from influxdata/master
Browse files Browse the repository at this point in the history
feat(inputs.x509_cert): add smtp protocol (influxdata#11271)
  • Loading branch information
sanekkurt authored Jun 15, 2022
2 parents f786d0d + 05285a1 commit 7a6c3f4
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
5 changes: 3 additions & 2 deletions plugins/inputs/x509_cert/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# x509 Certificate Input Plugin

This plugin provides information about X509 certificate accessible via local
file or network connection.
file, tcp, udp, https or smtp protocol.

When using a UDP address as a certificate source, the server must support
[DTLS](https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security).
Expand All @@ -14,7 +14,8 @@ When using a UDP address as a certificate source, the server must support
## List certificate sources, support wildcard expands for files
## Prefix your entry with 'file://' if you intend to use relative paths
sources = ["tcp://example.org:443", "https://influxdata.com:443",
"udp://127.0.0.1:4433", "/etc/ssl/certs/ssl-cert-snakeoil.pem",
"smtp://mail.localhost:25", "udp://127.0.0.1:4433",
"/etc/ssl/certs/ssl-cert-snakeoil.pem",
"/etc/mycerts/*.mydomain.org.pem", "file:///path/to/*.pem"]

## Timeout for SSL connection
Expand Down
3 changes: 2 additions & 1 deletion plugins/inputs/x509_cert/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
## List certificate sources, support wildcard expands for files
## Prefix your entry with 'file://' if you intend to use relative paths
sources = ["tcp://example.org:443", "https://influxdata.com:443",
"udp://127.0.0.1:4433", "/etc/ssl/certs/ssl-cert-snakeoil.pem",
"smtp://mail.localhost:25", "udp://127.0.0.1:4433",
"/etc/ssl/certs/ssl-cert-snakeoil.pem",
"/etc/mycerts/*.mydomain.org.pem", "file:///path/to/*.pem"]

## Timeout for SSL connection
Expand Down
48 changes: 48 additions & 0 deletions plugins/inputs/x509_cert/x509_cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/pem"
"fmt"
"net"
"net/smtp"
"net/url"
"os"
"path/filepath"
Expand Down Expand Up @@ -176,6 +177,53 @@ func (c *X509Cert) getCert(u *url.URL, timeout time.Duration) ([]*x509.Certifica
}
content = rest
}
return certs, nil
case "smtp":
ipConn, err := net.DialTimeout("tcp", u.Host, timeout)
if err != nil {
return nil, err
}
defer ipConn.Close()

serverName, err := c.serverName(u)
if err != nil {
return nil, err
}
c.tlsCfg.ServerName = serverName
c.tlsCfg.InsecureSkipVerify = true

smtpConn, err := smtp.NewClient(ipConn, u.Host)
if err != nil {
return nil, err
}

err = smtpConn.Hello(c.tlsCfg.ServerName)
if err != nil {
return nil, err
}

id, err := smtpConn.Text.Cmd("STARTTLS")
if err != nil {
return nil, err
}

smtpConn.Text.StartResponse(id)
defer smtpConn.Text.EndResponse(id)
_, _, err = smtpConn.Text.ReadResponse(220)
if err != nil {
return nil, fmt.Errorf("did not get 220 after STARTTLS: %s", err.Error())
}

tlsConn := tls.Client(ipConn, c.tlsCfg)
defer tlsConn.Close()

hsErr := tlsConn.Handshake()
if hsErr != nil {
return nil, hsErr
}

certs := tlsConn.ConnectionState().PeerCertificates

return certs, nil
default:
return nil, fmt.Errorf("unsupported scheme '%s' in location %s", u.Scheme, u.String())
Expand Down
4 changes: 2 additions & 2 deletions plugins/inputs/x509_cert/x509_cert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,12 @@ func TestGatherCertMustNotTimeout(t *testing.T) {

func TestSourcesToURLs(t *testing.T) {
m := &X509Cert{
Sources: []string{"https://www.influxdata.com:443", "tcp://influxdata.com:443", "file:///dummy_test_path_file.pem", "/tmp/dummy_test_path_glob*.pem"},
Sources: []string{"https://www.influxdata.com:443", "tcp://influxdata.com:443", "smtp://influxdata.com:25", "file:///dummy_test_path_file.pem", "/tmp/dummy_test_path_glob*.pem"},
}
require.NoError(t, m.Init())

require.Equal(t, len(m.globpaths), 2)
require.Equal(t, len(m.locations), 2)
require.Equal(t, len(m.locations), 3)
}

func TestServerName(t *testing.T) {
Expand Down

0 comments on commit 7a6c3f4

Please sign in to comment.