// MgoDialInfoTls returns a DialInfo suitable // for dialling an MgoInstance at any of the // given addresses, optionally using TLS. func MgoDialInfoTls(useTls bool, addrs ...string) *mgo.DialInfo { var dial func(addr net.Addr) (net.Conn, error) if useTls { pool := x509.NewCertPool() xcert, err := cert.ParseCert(CACert) if err != nil { panic(err) } pool.AddCert(xcert) tlsConfig := &tls.Config{ RootCAs: pool, ServerName: "anything", } dial = func(addr net.Addr) (net.Conn, error) { conn, err := tls.Dial("tcp", addr.String(), tlsConfig) if err != nil { logger.Debugf("tls.Dial(%s) failed with %v", addr, err) return nil, err } return conn, nil } } else { dial = func(addr net.Addr) (net.Conn, error) { conn, err := net.Dial("tcp", addr.String()) if err != nil { logger.Debugf("net.Dial(%s) failed with %v", addr, err) return nil, err } return conn, nil } } return &mgo.DialInfo{Addrs: addrs, Dial: dial, Timeout: mgoDialTimeout} }
// verifyKeyPair verifies that the certificate and key parse correctly. // The key is optional - if it is provided, we also check that the key // matches the certificate. func verifyKeyPair(certb, key string) error { if key != "" { _, err := tls.X509KeyPair([]byte(certb), []byte(key)) return err } _, err := cert.ParseCert(certb) return err }
// SetRsyslogCert sets the rsyslog CACert. func (api *RsyslogAPI) SetRsyslogCert(args params.SetRsyslogCertParams) (params.ErrorResult, error) { var result params.ErrorResult if !api.canModify { result.Error = common.ServerError(common.ErrBadCreds) return result, nil } if _, err := cert.ParseCert(string(args.CACert)); err != nil { result.Error = common.ServerError(err) return result, nil } attrs := map[string]interface{}{"rsyslog-ca-cert": string(args.CACert)} if err := api.st.UpdateEnvironConfig(attrs, nil, nil); err != nil { result.Error = common.ServerError(err) } return result, nil }
// DialInfo returns information on how to dial // the state's mongo server with the given info // and dial options. func DialInfo(info *Info, opts DialOpts) (*mgo.DialInfo, error) { if len(info.Addrs) == 0 { return nil, stderrors.New("no mongo addresses") } if len(info.CACert) == 0 { return nil, stderrors.New("missing CA certificate") } xcert, err := cert.ParseCert(info.CACert) if err != nil { return nil, fmt.Errorf("cannot parse CA certificate: %v", err) } pool := x509.NewCertPool() pool.AddCert(xcert) tlsConfig := &tls.Config{ RootCAs: pool, ServerName: "anything", } dial := func(addr net.Addr) (net.Conn, error) { c, err := net.Dial("tcp", addr.String()) if err != nil { logger.Debugf("connection failed, will retry: %v", err) return nil, err } cc := tls.Client(c, tlsConfig) if err := cc.Handshake(); err != nil { logger.Errorf("TLS handshake failed: %v", err) return nil, err } logger.Infof("dialled mongo successfully") return cc, nil } return &mgo.DialInfo{ Addrs: info.Addrs, Timeout: opts.Timeout, Dial: dial, }, nil }