diff options
-rw-r--r-- | config-sockets.txt | 12 | ||||
-rw-r--r-- | tls-getcerts.go | 125 |
2 files changed, 69 insertions, 68 deletions
diff --git a/config-sockets.txt b/config-sockets.txt index b152146..f121636 100644 --- a/config-sockets.txt +++ b/config-sockets.txt @@ -1,6 +1,6 @@ -tcp:proton.parabola.nu:443 -tcp:proton.parabola.nu:465 -tcp:winston.parabola.nu:443 -tcp:lukeshu.com:443 -tcp:team4272.com:443 -xmpp:parabola.nu:5222 +tcp://proton.parabola.nu:443 +tcp://proton.parabola.nu:465 +tcp://winston.parabola.nu:443 +tcp://lukeshu.com:443 +tcp://team4272.com:443 +tcp://parabola.nu:5222/xmpp diff --git a/tls-getcerts.go b/tls-getcerts.go index 7032199..c78436a 100644 --- a/tls-getcerts.go +++ b/tls-getcerts.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "net" + "net/url" "os" "strings" ) @@ -20,82 +21,82 @@ type xmppTlsProceed struct { XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls proceed"` } -func tlsDial(snet, saddr string) (*tls.Conn, error) { - switch snet { - case "tcp": - conn, err := tls.Dial(snet, saddr, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return nil, err - } - return conn, nil - case "xmpp": - host, _, err := net.SplitHostPort(saddr) - connTCP, err := net.Dial("tcp", saddr) - if err != nil { - return nil, err - } +func xmppStartTLS(connRaw net.Conn, host string) error { + decoder := xml.NewDecoder(connRaw) - decoder := xml.NewDecoder(connTCP) - - // send <stream> start - _, err = fmt.Fprintf(connTCP, "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='%s' version='1.0'>", host) - if err != nil { - return nil, err + // send <stream> start + _, err := fmt.Fprintf(connRaw, "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='%s' version='1.0'>", host) + if err != nil { + return err + } + // read <stream> start + for { + t, err := decoder.Token() + if err != nil || t == nil { + return err } - // read <stream> start - for { - t, err := decoder.Token() - if err != nil || t == nil { - return nil, err - } - if se, ok := t.(xml.StartElement); ok { - if se.Name.Local != "stream" { - return nil, xml.UnmarshalError(fmt.Sprintf("expected element of type <%s> but have <%s>", "stream", se.Name.Local)) - } - break + if se, ok := t.(xml.StartElement); ok { + if se.Name.Local != "stream" { + return xml.UnmarshalError(fmt.Sprintf("expected element of type <%s> but have <%s>", "stream", se.Name.Local)) } + break } - // read <features> - var features xmppStreamsFeatures - err = decoder.DecodeElement(&features, nil) - if err != nil { - return nil, err - } - // send <starttls> - _, err = io.WriteString(connTCP, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") - if err != nil { - return nil, err - } - // read <proceed> - var proceed xmppTlsProceed - err = decoder.DecodeElement(&proceed, nil) - if err != nil { - return nil, err - } - - connTLS := tls.Client(connTCP, &tls.Config{InsecureSkipVerify: true}) - err = connTLS.Handshake() - if err != nil { - return nil, err - } - return connTLS, nil - default: - return nil, fmt.Errorf("Unknown TLS network: %q", snet) } + // read <features> + var features xmppStreamsFeatures + err = decoder.DecodeElement(&features, nil) + if err != nil { + return err + } + // send <starttls> + _, err = io.WriteString(connRaw, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") + if err != nil { + return err + } + // read <proceed> + var proceed xmppTlsProceed + err = decoder.DecodeElement(&proceed, nil) + if err != nil { + return err + } + return nil } func getcert(socket string) (*x509.Certificate, error){ - snet, saddr := split(socket) - host, _, err := net.SplitHostPort(saddr) + u, err := url.Parse(socket) + if err != nil { + return nil, err + } + host, _, err := net.SplitHostPort(u.Host) if err != nil { return nil, err } - conn, err := tlsDial(snet, saddr) + + connRaw, err := net.Dial(u.Scheme, u.Host) if err != nil { return nil, err } - defer conn.Close() - cstate := conn.ConnectionState() + + switch u.Path { + case "", "/": + // do nothing + case "/xmpp": + err = xmppStartTLS(connRaw, host) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("Unknown negotiation path: %q", u.Path) + } + + connTLS := tls.Client(connRaw, &tls.Config{InsecureSkipVerify: true}) + defer connTLS.Close() + err = connTLS.Handshake() + if err != nil { + return nil, err + } + + cstate := connTLS.ConnectionState() opts := x509.VerifyOptions{ DNSName: host, |