func ExampleConvertToPEM() { var p12, _ = base64.StdEncoding.DecodeString(`MIIJzgIBAzCCCZQGCS ... CA+gwggPk==`) blocks, err := ConvertToPEM(p12, []byte("password")) if err != nil { panic(err) } pemData := []byte{} for _, b := range blocks { pemData = append(pemData, pem.EncodeToMemory(b)...) } // then use PEM data for tls to construct tls certificate: cert, err := tls.X509KeyPair(pemData, pemData) if err != nil { panic(err) } config := tls.Config{ Certificates: []tls.Certificate{cert}, } config.BuildNameToCertificate() for name := range config.NameToCertificate { fmt.Println(name) } }
// NewTLSConfig returns an initialized TLS configuration suitable for client // authentication. If caFile is non-empty, it will be loaded. func NewTLSConfig(caFile string, mutualTLS bool) (*tls.Config, error) { var c tls.Config // TLS 1.0 at a minimum (for mysql) c.MinVersion = tls.VersionTLS10 c.PreferServerCipherSuites = true if mutualTLS { log.Info("MutualTLS requested, client certificates will be verified") c.ClientAuth = tls.VerifyClientCertIfGiven } if caFile != "" { data, err := ioutil.ReadFile(caFile) if err != nil { return &c, err } c.ClientCAs = x509.NewCertPool() if !c.ClientCAs.AppendCertsFromPEM(data) { return &c, errors.New("No certificates parsed") } log.Info("Read in CA file:", caFile) } c.BuildNameToCertificate() return &c, nil }
func TestPEM(t *testing.T) { for commonName, base64P12 := range testdata { p12, _ := base64.StdEncoding.DecodeString(base64P12) blocks, err := ToPEM(p12, "") if err != nil { t.Fatalf("error while converting to PEM: %s", err) } var pemData []byte for _, b := range blocks { pemData = append(pemData, pem.EncodeToMemory(b)...) } cert, err := tls.X509KeyPair(pemData, pemData) if err != nil { t.Errorf("err while converting to key pair: %v", err) } config := tls.Config{ Certificates: []tls.Certificate{cert}, } config.BuildNameToCertificate() if _, exists := config.NameToCertificate[commonName]; !exists { t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate) } } }
func (cfg ConfigT) HttpsClient(tmout time.Duration) *http.Client { var httpclient http.Client var tlsConfig *tls.Config tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cfg.ClientCert}, RootCAs: cfg.ClientCA, InsecureSkipVerify: true, } tlsConfig.BuildNameToCertificate() httpclient = http.Client{ Transport: &http.Transport{ TLSClientConfig: tlsConfig, DisableCompression: true, }, } if tmout > time.Duration(0) { httpclient.Transport.(*http.Transport).Dial = func(network, addr string) (net.Conn, error) { return net.DialTimeout(network, addr, tmout) } } return &httpclient }
func getTLSConfig(clientCertPEMData, clientKeyPEMData []byte) (*tls.Config, error) { certPool := x509.NewCertPool() certChainPath := os.Getenv("ORCHARD_HOST_CA") if certChainPath != "" { certChainData, err := ioutil.ReadFile(certChainPath) if err != nil { return nil, err } certPool.AppendCertsFromPEM(certChainData) } else { certPool.AppendCertsFromPEM([]byte(orchardCerts)) } clientCert, err := tls.X509KeyPair(clientCertPEMData, clientKeyPEMData) if err != nil { return nil, err } config := new(tls.Config) config.RootCAs = certPool config.Certificates = []tls.Certificate{clientCert} config.BuildNameToCertificate() return config, nil }
//func (ck *CertKit) GetTLSConfig(AuthRequired bool) (*tls.Config, error) { func (ck *CertKit) GetTLSConfig(Access uint8) (*tls.Config, error) { var atype tls.ClientAuthType var tlsConfig *tls.Config var roots *x509.CertPool switch Access { case stonelizard.AccessNone: atype = tls.NoClientCert case stonelizard.AccessAuth, stonelizard.AccessAuthInfo: atype = tls.RequestClientCert case stonelizard.AccessVerifyAuth, stonelizard.AccessVerifyAuthInfo: atype = tls.RequireAndVerifyClientCert // Code adapted from crypto/x509/root_unix.go roots = x509.NewCertPool() for _, directory := range CertDirectories { fis, err := ioutil.ReadDir(directory) if err != nil { Goose.Auth.Logf(5, "Error scanning certificate directory %s: %s", directory, err) continue } for _, fi := range fis { data, err := ioutil.ReadFile(fmt.Sprintf("%s%c%s", directory, os.PathSeparator, fi.Name())) if err != nil { Goose.Auth.Logf(5, "Error load CA certificate from %s%c%s: %s", directory, os.PathSeparator, fi.Name(), err) continue } Goose.Auth.Logf(5, "Loaded CA certificate from %s%c%s: %s", directory, os.PathSeparator, fi.Name(), err) roots.AppendCertsFromPEM(data) } } } Goose.Auth.Logf(6, "authtype: %#v", atype) Goose.Auth.Logf(6, "CAs: %#v", roots) tlsConfig = &tls.Config{ ClientAuth: atype, ClientCAs: roots, // InsecureSkipVerify: true, Certificates: make([]tls.Certificate, 1), } /* srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(svc.PemPath + "/server.crt", svc.PemPath + "/server.key") if err != nil { Goose.InitServe.Logf(1,"Failed reading server certificates: %s",err) return err } */ tlsConfig.Certificates[0] = ck.ServerX509KeyPair Goose.Auth.Logf(5, "X509KeyPair used: %#v", tlsConfig.Certificates[0]) tlsConfig.BuildNameToCertificate() return tlsConfig, nil }
func NewNSQD(options *nsqdOptions) *NSQD { var tlsConfig *tls.Config if options.MaxDeflateLevel < 1 || options.MaxDeflateLevel > 9 { log.Fatalf("--max-deflate-level must be [1,9]") } tcpAddr, err := net.ResolveTCPAddr("tcp", options.TCPAddress) if err != nil { log.Fatal(err) } httpAddr, err := net.ResolveTCPAddr("tcp", options.HTTPAddress) if err != nil { log.Fatal(err) } if options.StatsdPrefix != "" { statsdHostKey := util.StatsdHostKey(net.JoinHostPort(options.BroadcastAddress, strconv.Itoa(httpAddr.Port))) prefixWithHost := strings.Replace(options.StatsdPrefix, "%s", statsdHostKey, -1) if prefixWithHost[len(prefixWithHost)-1] != '.' { prefixWithHost += "." } options.StatsdPrefix = prefixWithHost } if options.TLSCert != "" || options.TLSKey != "" { cert, err := tls.LoadX509KeyPair(options.TLSCert, options.TLSKey) if err != nil { log.Fatalf("ERROR: failed to LoadX509KeyPair %s", err.Error()) } tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.VerifyClientCertIfGiven, } tlsConfig.BuildNameToCertificate() } n := &NSQD{ options: options, tcpAddr: tcpAddr, httpAddr: httpAddr, topicMap: make(map[string]*Topic), idChan: make(chan nsq.MessageID, 4096), exitChan: make(chan int), notifyChan: make(chan interface{}), tlsConfig: tlsConfig, } n.waitGroup.Wrap(func() { n.idPump() }) return n }
func httpClient() (client *http.Client) { chain := rootCertificate() config := tls.Config{} config.RootCAs = x509.NewCertPool() for _, cert := range chain.Certificate { x509Cert, err := x509.ParseCertificate(cert) if err != nil { panic(err) } config.RootCAs.AddCert(x509Cert) } config.BuildNameToCertificate() tr := http.Transport{TLSClientConfig: &config} client = &http.Client{Transport: &tr} return }
// Include our root certificate in TLS. // // THIS IS A MODIFICATION TO THE ORIGINAL // VERSION OF THE SOURCE CODE. // CHANGED ON SEPTEMBER 05, 2013 // // This builds on the gist available at: // https://gist.github.com/laher/5795578 // and is meant to resolve the error: // "x509: failed to load system roots and no roots provided" // This happens since cross-compiling disables cgo - // however cgo is required to find system root // certificates on darwin machines. Note that the client // returned can only connect successfully to the // supplied s3's region. func getHttpClient(s3 *S3) (*http.Client, error) { // get the pem string by running openssl. Note that the // endpoint will only work for the regional s3 endpoint // supplied out, err := exec.Command("openssl", "s_client", "-showcerts", "-connect", strings.Replace(s3.Region.S3Endpoint, "https://", "", -1)+":443").Output() if err != nil { return nil, err } certInput := string(out) // decode the pem string returned by openssl var certChain tls.Certificate certPEMBlock := []byte(certInput) var certDERBlock *pem.Block for { certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) if certDERBlock == nil { break } if certDERBlock.Type == "CERTIFICATE" { certChain.Certificate = append(certChain.Certificate, certDERBlock.Bytes) } } // inititalize our tls certificate config conf := tls.Config{} // we're creating a new cert pool here // to use for TLS conf.RootCAs = x509.NewCertPool() for _, cert := range certChain.Certificate { x509Cert, err := x509.ParseCertificate(cert) if err != nil { return nil, err } conf.RootCAs.AddCert(x509Cert) } // map certificate names to actual certificates conf.BuildNameToCertificate() // create a Transport which inlcudes our TLS config tr := http.Transport{TLSClientConfig: &conf} // add the Transport to our http client return &http.Client{Transport: &tr}, nil }
// ListenAndServeTLSWithSNI serves TLS with Server Name Indication (SNI) support, which allows // multiple sites (different hostnames) to be served from the same address. This method is // adapted directly from the std lib's net/http ListenAndServeTLS function, which was // written by the Go Authors. It has been modified to support multiple certificate/key pairs. func ListenAndServeTLSWithSNI(srv *http.Server, tlsConfigs []TLSConfig) error { addr := srv.Addr if addr == "" { addr = ":https" } config := new(tls.Config) if srv.TLSConfig != nil { *config = *srv.TLSConfig } if config.NextProtos == nil { config.NextProtos = []string{"http/1.1"} } // Here we diverge from the stdlib a bit by loading multiple certs/key pairs // then we map the server names to their certs var err error config.Certificates = make([]tls.Certificate, len(tlsConfigs)) for i, tlsConfig := range tlsConfigs { config.Certificates[i], err = tls.LoadX509KeyPair(tlsConfig.Certificate, tlsConfig.Key) if err != nil { return err } } config.BuildNameToCertificate() // Customize our TLS configuration config.MinVersion = tlsConfigs[0].ProtocolMinVersion config.MaxVersion = tlsConfigs[0].ProtocolMaxVersion config.CipherSuites = tlsConfigs[0].Ciphers config.PreferServerCipherSuites = tlsConfigs[0].PreferServerCipherSuites // TLS client authentication, if user enabled it err = setupClientAuth(tlsConfigs, config) if err != nil { return err } // Create listener and we're on our way conn, err := net.Listen("tcp", addr) if err != nil { return err } tlsListener := tls.NewListener(conn, config) return srv.Serve(tlsListener) }
func buildTLSConfig(opts *nsqd.Options) (*tls.Config, error) { var tlsConfig *tls.Config if opts.TLSCert == "" && opts.TLSKey == "" { return nil, nil } tlsClientAuthPolicy := tls.VerifyClientCertIfGiven cert, err := tls.LoadX509KeyPair(opts.TLSCert, opts.TLSKey) if err != nil { return nil, err } switch opts.TLSClientAuthPolicy { case "require": tlsClientAuthPolicy = tls.RequireAnyClientCert case "require-verify": tlsClientAuthPolicy = tls.RequireAndVerifyClientCert default: tlsClientAuthPolicy = tls.NoClientCert } tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tlsClientAuthPolicy, MinVersion: opts.TLSMinVersion, MaxVersion: tls.VersionTLS12, // enable TLS_FALLBACK_SCSV prior to Go 1.5: https://go-review.googlesource.com/#/c/1776/ } if opts.TLSRootCAFile != "" { tlsCertPool := x509.NewCertPool() caCertFile, err := ioutil.ReadFile(opts.TLSRootCAFile) if err != nil { return nil, err } if !tlsCertPool.AppendCertsFromPEM(caCertFile) { return nil, errors.New("failed to append certificate to pool") } tlsConfig.ClientCAs = tlsCertPool } tlsConfig.BuildNameToCertificate() return tlsConfig, nil }
func buildTLSConfig(opts *nsqdOptions) (*tls.Config, error) { var tlsConfig *tls.Config if opts.TLSCert == "" && opts.TLSKey == "" { return nil, nil } tlsClientAuthPolicy := tls.VerifyClientCertIfGiven cert, err := tls.LoadX509KeyPair(opts.TLSCert, opts.TLSKey) if err != nil { return nil, err } switch opts.TLSClientAuthPolicy { case "require": tlsClientAuthPolicy = tls.RequireAnyClientCert case "require-verify": tlsClientAuthPolicy = tls.RequireAndVerifyClientCert default: tlsClientAuthPolicy = tls.NoClientCert } tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tlsClientAuthPolicy, } if opts.TLSRootCAFile != "" { tlsCertPool := x509.NewCertPool() ca_cert_file, err := ioutil.ReadFile(opts.TLSRootCAFile) if err != nil { return nil, err } if !tlsCertPool.AppendCertsFromPEM(ca_cert_file) { return nil, errors.New("failed to append certificate to pool") } tlsConfig.ClientCAs = tlsCertPool } tlsConfig.BuildNameToCertificate() return tlsConfig, nil }
func buildTLSConfig(options *nsqdOptions) *tls.Config { var tlsConfig *tls.Config if options.TLSCert == "" && options.TLSKey == "" { return nil } tlsClientAuthPolicy := tls.VerifyClientCertIfGiven cert, err := tls.LoadX509KeyPair(options.TLSCert, options.TLSKey) if err != nil { log.Fatalf("ERROR: failed to LoadX509KeyPair %s", err.Error()) } switch options.TLSClientAuthPolicy { case "require": tlsClientAuthPolicy = tls.RequireAnyClientCert case "require-verify": tlsClientAuthPolicy = tls.RequireAndVerifyClientCert default: tlsClientAuthPolicy = tls.NoClientCert } tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tlsClientAuthPolicy, } if options.TLSRootCAFile != "" { tlsCertPool := x509.NewCertPool() ca_cert_file, err := ioutil.ReadFile(options.TLSRootCAFile) if err != nil { log.Fatalf("ERROR: failed to read custom Certificate Authority file %s", err.Error()) } if !tlsCertPool.AppendCertsFromPEM(ca_cert_file) { log.Fatalf("ERROR: failed to append certificates from Certificate Authority file") } tlsConfig.ClientCAs = tlsCertPool } tlsConfig.BuildNameToCertificate() return tlsConfig }
func ListenAndServeTLSWithSNI(srv *http.Server, tlsConfigs []TLSConfig) error { addr := srv.Addr if addr == "" { addr = ":https" } config := new(tls.Config) if srv.TLSConfig != nil { *config = *srv.TLSConfig } if config.NextProtos == nil { config.NextProtos = []string{"http/1.1"} } var err error config.Certificates = make([]tls.Certificate, len(tlsConfigs)) for i, tlsConfig := range tlsConfigs { config.Certificates[i], err = tls.LoadX509KeyPair(tlsConfig.Certificate, tlsConfig.Key) if err != nil { return err } } config.BuildNameToCertificate() config.MinVersion = tlsConfigs[0].ProtocolMinVersion config.MaxVersion = tlsConfigs[0].ProtocolMaxVersion config.CipherSuites = tlsConfigs[0].Ciphers config.PreferServerCipherSuites = tlsConfigs[0].PreferServerCipherSuites err = setupClientAuth(tlsConfigs, config) if err != nil { return err } conn, err := net.Listen("tcp", addr) if err != nil { return err } tlsListener := tls.NewListener(conn, config) return srv.Serve(tlsListener) }
func httpClient() (client *http.Client) { if CustomEndpoint == "" { chain := rootCertificate() config := tls.Config{InsecureSkipVerify: true} config.RootCAs = x509.NewCertPool() for _, cert := range chain.Certificate { x509Cert, err := x509.ParseCertificate(cert) if err != nil { panic(err) } config.RootCAs.AddCert(x509Cert) } config.BuildNameToCertificate() tr := http.Transport{TLSClientConfig: &config} client = &http.Client{Transport: &tr} } else { client = &http.Client{} } return }
func NewBroker(options *brokerOptions) *Broker { var tlsConfig *tls.Config if options.MaxDeflateLevel < 1 || options.MaxDeflateLevel > 9 { log.Fatalf("--max-deflate-level must be [1,9]") } tcpAddr, err := net.ResolveTCPAddr("tcp", options.TCPAddress) if err != nil { log.Fatal(err) } httpAddr, err := net.ResolveTCPAddr("tcp", options.HTTPAddress) if err != nil { log.Fatal(err) } if options.TLSCert != "" || options.TLSKey != "" { cert, err := tls.LoadX509KeyPair(options.TLSCert, options.TLSKey) if err != nil { log.Fatalf("ERROR: failed to LoadX509KeyPair %s", err.Error()) } tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, ClientAuth: tls.VerifyClientCertIfGiven, } tlsConfig.BuildNameToCertificate() } b := &Broker{ options: options, tcpAddr: tcpAddr, httpAddr: httpAddr, clients: make(map[string]*client, DefaultClientMapSize), //default client map size exitChan: make(chan int), // notifyChan: make(chan interface{}), tlsConfig: tlsConfig, } return b }
func finalizeTLSConfig(tlsConfig *tls.Config, tlsRemoteCert *x509.Certificate) { // Trusted certificates if tlsRemoteCert != nil { caCertPool := x509.NewCertPool() // Make it a valid RootCA tlsRemoteCert.IsCA = true tlsRemoteCert.KeyUsage = x509.KeyUsageCertSign // Setup the pool caCertPool.AddCert(tlsRemoteCert) tlsConfig.RootCAs = caCertPool // Set the ServerName if tlsRemoteCert.DNSNames != nil { tlsConfig.ServerName = tlsRemoteCert.DNSNames[0] } } tlsConfig.BuildNameToCertificate() }
// tlsConfig builds a *tls.Config from the given options. func tlsConfig(insecure bool, certf, keyf string, rootCerts []string) (*tls.Config, error) { var err error files := map[string][]byte{} filenames := append([]string{certf, keyf}, rootCerts...) for _, f := range filenames { if f != "" { if files[f], err = ioutil.ReadFile(f); err != nil { return nil, err } } } c := tls.Config{InsecureSkipVerify: insecure} if cert, ok := files[certf]; ok { key, ok := files[keyf] if !ok { key = cert } certificate, err := tls.X509KeyPair(cert, key) if err != nil { return nil, err } c.Certificates = append(c.Certificates, certificate) c.BuildNameToCertificate() } if len(rootCerts) > 0 { c.RootCAs = x509.NewCertPool() for _, f := range rootCerts { if !c.RootCAs.AppendCertsFromPEM(files[f]) { return nil, errBadCert } } } return &c, nil }
func loadTLS(keyPath, certPath string) (*tls.Config, error) { tlsConfig := new(tls.Config) tlsConfig.PreferServerCipherSuites = true tlsConfig.CipherSuites = []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, tls.TLS_RSA_WITH_AES_256_CBC_SHA, tls.TLS_RSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA} cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { logging.Error("config", "Error loading tls certificate and key files.") logging.Error("config", err.Error()) return nil, err } tlsConfig.Certificates = []tls.Certificate{cert} tlsConfig.BuildNameToCertificate() return tlsConfig, nil }
func GetConfig(ca_f []byte, ee_f []byte, key_f []byte) (*tls.Config, error) { ca, err := x509.ParseCertificate(ca_f) if err != nil { return nil, err } pkey, err := x509.ParsePKCS1PrivateKey(key_f) if err != nil { return nil, err } ca_pool := x509.NewCertPool() ca_pool.AddCert(ca) ee_cert := tls.Certificate{ Certificate: [][]byte{ee_f}, PrivateKey: pkey, } config := new(tls.Config) config.ClientAuth = tls.RequireAndVerifyClientCert config.Certificates = []tls.Certificate{ee_cert} config.ClientCAs = ca_pool config.RootCAs = ca_pool config.Rand = rand.Reader config.BuildNameToCertificate() return config, nil }
func main() { flag.Parse() log.Printf("Rosella v%s Initialising.", VERSION) //Init rosella itself server := NewServer() server.name = *serverName if *authFile != "" { log.Printf("Loading auth file: %q", *authFile) f, err := os.Open(*authFile) if err != nil { log.Fatal(err) } data := make([]byte, 1024) size, err := f.Read(data) if err != nil { log.Fatal(err) } lines := strings.Split(string(data[:size]), "\n") for _, line := range lines { if strings.HasPrefix(line, "#") { continue } fields := strings.Fields(line) if len(fields) == 2 { server.operatorMap[fields[0]] = fields[1] } } } if *motdFile != "" { log.Printf("Loading motd file: %q", *motdFile) f, err := os.Open(*motdFile) if err != nil { log.Fatal(err) } data := make([]byte, 1024) size, err := f.Read(data) if err != nil { log.Fatal(err) } server.motd = string(data[:size]) } go server.Run() tlsConfig := new(tls.Config) tlsConfig.PreferServerCipherSuites = true tlsConfig.CipherSuites = []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, tls.TLS_RSA_WITH_AES_256_CBC_SHA, tls.TLS_RSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA} cert, err := tls.LoadX509KeyPair(*tlsCertFile, *tlsKeyFile) if err != nil { log.Printf("Error loading tls certificate and key files.") log.Printf(err.Error()) return } log.Printf("Loaded certificate and key successfully.") tlsConfig.Certificates = []tls.Certificate{cert} //Fills out tlsConfig.NameToCertificate tlsConfig.BuildNameToCertificate() tlsListener, err := tls.Listen("tcp", *ircAddress, tlsConfig) if err != nil { log.Printf("Could not open tls listener.") log.Printf(err.Error()) return } log.Printf("Listening on %s", *ircAddress) if syscall.Getuid() == 0 { if *groupId < 1 || *userId < 1 { log.Printf("Rosella may not be run as root. Please specify a non-root uid and gid that it may drop to.") return } if syscall.Setgid(*groupId) != nil { log.Printf("Failed to set gid to %i", *groupId) return } if syscall.Setuid(*userId) != nil { log.Printf("Failed to set uid to %i", *userId) return } } for { conn, err := tlsListener.Accept() if err != nil { log.Printf("Error accepting connection.") log.Printf(err.Error()) continue } server.HandleConnection(conn) } }
func main() { devP := flag.Bool("d", false, "use development push server") flag.Parse() if flag.NArg() < 1 { log.Fatalf("usage: %s [-d] cert.p12", os.Args[0]) } var server string if *devP { server = "api.development.push.apple.com" } else { server = "api.push.apple.com" } d, err := ioutil.ReadFile(flag.Arg(0)) if err != nil { log.Fatal(err) } key, cert, err := pkcs12.Decode(d, "") if err != nil { log.Fatal(err) } tlsConfig := tls.Config{ Certificates: []tls.Certificate{{ Certificate: [][]byte{cert.Raw}, PrivateKey: key.(*rsa.PrivateKey), }}, } tlsConfig.BuildNameToCertificate() client := http.Client{ Transport: &http2.Transport{ TLSClientConfig: &tlsConfig, }, } scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { var notification Notification err := json.Unmarshal([]byte(scanner.Text()), ¬ification) if err != nil { log.Fatal(err) } resp, err := client.Post(fmt.Sprintf( "https://%s/3/device/%s", server, url.QueryEscape(notification.Token), ), "", bytes.NewReader(notification.Payload)) if err != nil { log.Fatal(err) } defer resp.Body.Close() var buf bytes.Buffer buf.ReadFrom(resp.Body) var rawRes *json.RawMessage if len(buf.Bytes()) != 0 { rm := json.RawMessage(buf.Bytes()) rawRes = &rm } json, err := json.Marshal(struct { Status int `json:"status"` Body *json.RawMessage `json:"body,omitempty"` }{resp.StatusCode, rawRes}) if err != nil { log.Fatal(err) } os.Stdout.Write(json) os.Stdout.Write([]byte{'\n'}) } if err := scanner.Err(); err != nil { log.Fatal(err) } }
// CreateConsulClient creates a new Consul API client from the given input. func (c *ClientSet) CreateConsulClient(i *CreateConsulClientInput) error { consulConfig := consulapi.DefaultConfig() if i.Address != "" { consulConfig.Address = i.Address } if i.Token != "" { consulConfig.Token = i.Token } if i.AuthEnabled { consulConfig.HttpAuth = &consulapi.HttpBasicAuth{ Username: i.AuthUsername, Password: i.AuthPassword, } } // This transport will attempt to keep connections open to the Consul server. transport := cleanhttp.DefaultPooledTransport() // Configure SSL if i.SSLEnabled { consulConfig.Scheme = "https" var tlsConfig tls.Config // Custom certificate or certificate and key if i.SSLCert != "" && i.SSLKey != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLKey) if err != nil { return fmt.Errorf("client set: consul: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } else if i.SSLCert != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLCert) if err != nil { return fmt.Errorf("client set: consul: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Custom CA certificate if i.SSLCACert != "" || i.SSLCAPath != "" { rootConfig := &rootcerts.Config{ CAFile: i.SSLCACert, CAPath: i.SSLCAPath, } if err := rootcerts.ConfigureTLS(&tlsConfig, rootConfig); err != nil { return fmt.Errorf("client set: consul configuring TLS failed: %s", err) } } // Construct all the certificates now tlsConfig.BuildNameToCertificate() // SSL verification if i.ServerName != "" { tlsConfig.ServerName = i.ServerName tlsConfig.InsecureSkipVerify = false } if !i.SSLVerify { log.Printf("[WARN] (clients) disabling consul SSL verification") tlsConfig.InsecureSkipVerify = true } // Save the TLS config on our transport transport.TLSClientConfig = &tlsConfig } // Setup the new transport consulConfig.HttpClient.Transport = transport // Create the API client client, err := consulapi.NewClient(consulConfig) if err != nil { return fmt.Errorf("client set: consul: %s", err) } // Save the data on ourselves c.Lock() c.consul = &consulClient{ client: client, httpClient: consulConfig.HttpClient, } c.Unlock() return nil }
func (c *ClientSet) CreateVaultClient(i *CreateVaultClientInput) error { vaultConfig := vaultapi.DefaultConfig() if i.Address != "" { vaultConfig.Address = i.Address } // This transport will attempt to keep connections open to the Vault server. transport := cleanhttp.DefaultPooledTransport() // Configure SSL if i.SSLEnabled { var tlsConfig tls.Config // Custom certificate or certificate and key if i.SSLCert != "" && i.SSLKey != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLKey) if err != nil { return fmt.Errorf("client set: vault: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } else if i.SSLCert != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLCert) if err != nil { return fmt.Errorf("client set: vault: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Custom CA certificate if i.SSLCACert != "" || i.SSLCAPath != "" { rootConfig := &rootcerts.Config{ CAFile: i.SSLCACert, CAPath: i.SSLCAPath, } if err := rootcerts.ConfigureTLS(&tlsConfig, rootConfig); err != nil { return fmt.Errorf("client set: vault configuring TLS failed: %s", err) } } // Construct all the certificates now tlsConfig.BuildNameToCertificate() // SSL verification if i.ServerName != "" { tlsConfig.ServerName = i.ServerName tlsConfig.InsecureSkipVerify = false } if !i.SSLVerify { log.Printf("[WARN] (clients) disabling vault SSL verification") tlsConfig.InsecureSkipVerify = true } // Save the TLS config on our transport transport.TLSClientConfig = &tlsConfig } // Setup the new transport vaultConfig.HttpClient.Transport = transport // Create the client client, err := vaultapi.NewClient(vaultConfig) if err != nil { return fmt.Errorf("client set: vault: %s", err) } // Set the token if given if i.Token != "" { client.SetToken(i.Token) } // Check if we are unwrapping if i.UnwrapToken { secret, err := client.Logical().Unwrap(i.Token) if err != nil { return fmt.Errorf("client set: vault unwrap: %s", err) } if secret == nil { return fmt.Errorf("client set: vault unwrap: no secret") } if secret.Auth == nil { return fmt.Errorf("client set: vault unwrap: no secret auth") } if secret.Auth.ClientToken == "" { return fmt.Errorf("client set: vault unwrap: no token returned") } client.SetToken(secret.Auth.ClientToken) } // Save the data on ourselves c.Lock() c.vault = &vaultClient{ client: client, httpClient: vaultConfig.HttpClient, } c.Unlock() return nil }
func StartClient(url_, heads, requestBody string, meth string, dka bool, responseChan chan *Response, waitGroup *sync.WaitGroup, tc int) { defer waitGroup.Done() var tr *http.Transport u, err := url.Parse(url_) if err == nil && u.Scheme == "https" { var tlsConfig *tls.Config if *insecure { tlsConfig = &tls.Config{ InsecureSkipVerify: true, } } else { // Load client cert cert, err := tls.LoadX509KeyPair(*certFile, *keyFile) if err != nil { log.Fatal(err) } // Load CA cert caCert, err := ioutil.ReadFile(*caFile) if err != nil { log.Fatal(err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) // Setup HTTPS client tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, RootCAs: caCertPool, } tlsConfig.BuildNameToCertificate() } tr = &http.Transport{TLSClientConfig: tlsConfig, DisableKeepAlives: dka} } else { tr = &http.Transport{DisableKeepAlives: dka} } requestBodyReader := strings.NewReader(requestBody) req, _ := http.NewRequest(meth, url_, requestBodyReader) sets := strings.Split(heads, "\n") //Split incoming header string by \n and build header pairs for i := range sets { split := strings.SplitN(sets[i], ":", 2) if len(split) == 2 { req.Header.Set(split[0], split[1]) } } timer := NewTimer() for { timer.Reset() resp, err := tr.RoundTrip(req) respObj := &Response{} if err != nil { respObj.Error = true } else { if resp.ContentLength < 0 { // -1 if the length is unknown data, err := ioutil.ReadAll(resp.Body) if err == nil { respObj.Size = int64(len(data)) } } else { respObj.Size = resp.ContentLength } respObj.StatusCode = resp.StatusCode resp.Body.Close() } respObj.Duration = timer.Duration() if len(responseChan) >= tc { break } responseChan <- respObj } }
func (c *ClientSet) CreateVaultClient(i *CreateVaultClientInput) error { log.Printf("[INFO] (clients) creating vault/api client") // Generate the default config vaultConfig := vaultapi.DefaultConfig() // Set the address if i.Address != "" { log.Printf("[DEBUG] (clients) setting vault address to %q", i.Address) vaultConfig.Address = i.Address } // This transport will attempt to keep connections open to the Vault server. transport := cleanhttp.DefaultPooledTransport() // Configure SSL if i.SSLEnabled { log.Printf("[DEBUG] (clients) enabling vault SSL") var tlsConfig tls.Config // Custom certificate or certificate and key if i.SSLCert != "" && i.SSLKey != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLKey) if err != nil { return fmt.Errorf("client set: vault: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } else if i.SSLCert != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLCert) if err != nil { return fmt.Errorf("client set: vault: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Custom CA certificate if i.SSLCACert != "" { cacert, err := ioutil.ReadFile(i.SSLCACert) if err != nil { return fmt.Errorf("client set: vault: %s", err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(cacert) tlsConfig.RootCAs = caCertPool } // Construct all the certificates now tlsConfig.BuildNameToCertificate() // SSL verification if !i.SSLVerify { log.Printf("[WARN] (clients) disabling vault SSL verification") tlsConfig.InsecureSkipVerify = true } // Save the TLS config on our transport transport.TLSClientConfig = &tlsConfig } // Setup the new transport vaultConfig.HttpClient.Transport = transport // Create the client client, err := vaultapi.NewClient(vaultConfig) if err != nil { return fmt.Errorf("client set: vault: %s", err) } // Set the token if given if i.Token != "" { log.Printf("[DEBUG] (clients) setting vault token") client.SetToken(i.Token) } // Check if we are unwrapping if i.UnwrapToken { log.Printf("[INFO] (clients) unwrapping vault token") secret, err := client.Logical().Unwrap(i.Token) if err != nil { return fmt.Errorf("client set: vault unwrap: %s", err) } if secret == nil { return fmt.Errorf("client set: vault unwrap: no secret") } if secret.Auth == nil { return fmt.Errorf("client set: vault unwrap: no secret auth") } if secret.Auth.ClientToken == "" { return fmt.Errorf("client set: vault unwrap: no token returned") } client.SetToken(secret.Auth.ClientToken) } // Save the data on ourselves c.vault = &vaultClient{ client: client, httpClient: vaultConfig.HttpClient, } return nil }
// CreateConsulClient creates a new Consul API client from the given input. func (c *ClientSet) CreateConsulClient(i *CreateConsulClientInput) error { log.Printf("[INFO] (clients) creating consul/api client") // Generate the default config consulConfig := consulapi.DefaultConfig() // Set the address if i.Address != "" { log.Printf("[DEBUG] (clients) setting consul address to %q", i.Address) consulConfig.Address = i.Address } // Configure the token if i.Token != "" { log.Printf("[DEBUG] (clients) setting consul token") consulConfig.Token = i.Token } // Add basic auth if i.AuthEnabled { log.Printf("[DEBUG] (clients) setting basic auth") consulConfig.HttpAuth = &consulapi.HttpBasicAuth{ Username: i.AuthUsername, Password: i.AuthPassword, } } // This transport will attempt to keep connections open to the Consul server. transport := cleanhttp.DefaultPooledTransport() // Configure SSL if i.SSLEnabled { log.Printf("[DEBUG] (clients) enabling consul SSL") consulConfig.Scheme = "https" var tlsConfig tls.Config // Custom certificate or certificate and key if i.SSLCert != "" && i.SSLKey != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLKey) if err != nil { return fmt.Errorf("client set: consul: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } else if i.SSLCert != "" { cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLCert) if err != nil { return fmt.Errorf("client set: consul: %s", err) } tlsConfig.Certificates = []tls.Certificate{cert} } // Custom CA certificate if i.SSLCACert != "" { cacert, err := ioutil.ReadFile(i.SSLCACert) if err != nil { return fmt.Errorf("client set: consul: %s", err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(cacert) tlsConfig.RootCAs = caCertPool } // Construct all the certificates now tlsConfig.BuildNameToCertificate() // SSL verification if !i.SSLVerify { log.Printf("[WARN] (clients) disabling consul SSL verification") tlsConfig.InsecureSkipVerify = true } // Save the TLS config on our transport transport.TLSClientConfig = &tlsConfig } // Setup the new transport consulConfig.HttpClient.Transport = transport // Create the API client client, err := consulapi.NewClient(consulConfig) if err != nil { return fmt.Errorf("client set: consul: %s", err) } // Save the data on ourselves c.consul = &consulClient{ client: client, httpClient: consulConfig.HttpClient, } return nil }
// Process a single connection. func process(cid int, nc net.Conn, certs []tls.Certificate, logf io.Writer, smtplog io.Writer, baserules []*Rule) { var evt smtpd.EventInfo var convo *smtpd.Conn var logger *smtpLogger var l2 io.Writer var gotsomewhere, stall, sesscounts bool var cfg smtpd.Config defer nc.Close() trans := &smtpTransaction{} trans.savedir = savedir trans.raddr = nc.RemoteAddr() trans.laddr = nc.LocalAddr() prefix := fmt.Sprintf("%d/%d", os.Getpid(), cid) trans.rip, _, _ = net.SplitHostPort(trans.raddr.String()) trans.lip, _, _ = net.SplitHostPort(trans.laddr.String()) var c *Context // nit: in the presence of yakkers, we must know whether or not // the rules are good because bad rules turn *everyone* into // yakkers (since they prevent clients from successfully EHLO'ing). rules, rulesgood := setupRules(baserules) // A yakker is a client that is repeatedly connecting to us // without doing anything successfully. After a certain number // of attempts we turn them off. We only do this if we're logging // SMTP commands; if we're not logging, we don't care. // This is kind of a hack, but this code is for Chris and this is // what Chris cares about. // sesscounts is true if this session should count for being a // 'bad' session if we don't get far enough. Sessions with TLS // errors don't count, as do sessions with bad rules or sessions // where yakCount == 0. sesscounts = rulesgood && yakCount > 0 hit, cnt := yakkers.Lookup(trans.rip, yakTimeout) if yakCount > 0 && hit && cnt >= yakCount && smtplog != nil { // nit: if the rules are bad and we're stalling anyways, // yakkers still have their SMTP transactions not logged. c = newContext(trans, stallall) stall = true sesscounts = false } else { c = newContext(trans, rules) } //fmt.Printf("rules are:\n%+v\n", c.ruleset) if smtplog != nil && !stall { logger = &smtpLogger{} logger.prefix = []byte(prefix) logger.writer = bufio.NewWriterSize(smtplog, 8*1024) trans.log = logger l2 = logger } sname := trans.laddr.String() if srvname != "" { sname = srvname } else { lip, _, _ := net.SplitHostPort(sname) // we don't do a verified lookup of the local IP address // because it's theoretically under your control, so if // you want to forge stuff that's up to you. nlst, err := net.LookupAddr(lip) if err == nil && len(nlst) > 0 { sname = nlst[0] if sname[len(sname)-1] == '.' { sname = sname[:len(sname)-1] } } } if connfile != "" { dm, err := loadConnFile(connfile) if err != nil { warnf("error loading per-connection rules '%s': %s\n", connfile, err) } // dm.find() explicitly works even on nil dm, so we don't // need to guard it. if pd := dm.find(nc); pd != nil { if pd.myname != "" { sname = pd.myname } certs = pd.certs } } cfg.LocalName = sname cfg.SayTime = true cfg.SftName = "sinksmtp" cfg.Announce = "This server does not deliver email." // stalled conversations are always slow, even if -S is not set. // TODO: make them even slower than this? I probably don't care. if goslow || stall { cfg.Delay = time.Second / 10 } // Don't offer TLS to hosts that have too many TLS failures. // We give hosts *two* tries at setting up TLS because some // hosts start by offering SSLv2, which is an instant-fail, // even if they support stuff that we do. We hope that their // SSLv2 failure will cause them to try again in another // connection with TLS only. // See https://code.google.com/p/go/issues/detail?id=3930 blocktls, blcount := notls.Lookup(trans.rip, tlsTimeout) if len(certs) > 0 && !(blocktls && blcount >= 2) { var tlsc tls.Config tlsc.Certificates = certs // if there is already one TLS failure for this host, // it might be because of a bad client certificate. // so on the second time around we don't ask for one. // (More precisely we only ask for a client cert if // there are no failures so far.) // Another reason for failure here is a SSLv3 only // host without a client certificate. This produces // the error: // tls: received unexpected handshake message of type *tls.clientKeyExchangeMsg when waiting for *tls.certificateMsg //if blcount == 0 { // tlsc.ClientAuth = tls.VerifyClientCertIfGiven //} // Now generally disabled since I discovered it causes // SSLv3 handshakes to always fail. TODO: better fix with // config-file control or something. tlsc.SessionTicketsDisabled = true tlsc.ServerName = sname tlsc.BuildNameToCertificate() cfg.TLSConfig = &tlsc } // With everything set up we can now create the connection. convo = smtpd.NewConn(nc, cfg, l2) // Yes, we do rDNS lookup before our initial greeting banner and // thus can pause a bit here. Clients will cope, or at least we // don't care if impatient ones don't. trans.rdns, _ = LookupAddrVerified(trans.rip) // Check for an immediate result on the initial connection. This // may disable TLS or refuse things immediately. if decider(pConnect, evt, c, convo, "") { // TODO: somehow write a message and maybe log it. // this probably needs smtpd.go cooperation. // Right now we just close abruptly. if !stall { writeLog(logger, "! %s dropped on connect due to rule at %s\n", trans.rip, time.Now().Format(smtpd.TimeFmt)) } return } // Main transaction loop. We gather up email messages as they come // in, possibly failing various operations as we're told to. for { evt = convo.Next() switch evt.What { case smtpd.COMMAND: switch evt.Cmd { case smtpd.EHLO, smtpd.HELO: if decider(pHelo, evt, c, convo, "") { continue } trans.heloname = evt.Arg trans.from = "" trans.data = "" trans.hash = "" trans.bodyhash = "" trans.rcptto = []string{} if minphase == "helo" { gotsomewhere = true } case smtpd.MAILFROM: if decider(pMfrom, evt, c, convo, "") { continue } if trans.from != "" && !gotsomewhere && sesscounts { // We've been RSET, which potentially // counts as a failure for do-nothing // client detection. Note that we are // implicitly adding the *last* failed // attempt, the one that was RSET from. cnt = yakkers.Add(trans.rip, yakTimeout) // We're slightly generous with RSETs. // This has no net effect unless this // final attempt succeeds. if cnt > yakCount { writeLog(logger, "! %s added as a yakker at hit %d due to RSET\n", trans.rip, cnt) convo.TempfailMsg("Too many unsuccessful delivery attempts") // this will implicitly close // the connection. return } } trans.from = evt.Arg trans.data = "" trans.rcptto = []string{} if minphase == "from" { gotsomewhere = true } doAccept(convo, c, "") case smtpd.RCPTTO: if decider(pRto, evt, c, convo, "") { continue } trans.rcptto = append(trans.rcptto, evt.Arg) if minphase == "to" { gotsomewhere = true } doAccept(convo, c, "") case smtpd.DATA: if decider(pData, evt, c, convo, "") { continue } if minphase == "data" { gotsomewhere = true } doAccept(convo, c, "") } case smtpd.GOTDATA: // -minphase=message means 'message // successfully transmitted to us' as opposed // to 'message accepted'. if minphase == "message" { gotsomewhere = true } // message rejection is deferred until after logging // et al. trans.data = evt.Arg trans.when = time.Now() trans.tlson = convo.TLSOn trans.cipher = convo.TLSState.CipherSuite trans.servername = convo.TLSState.ServerName trans.tlsversion = convo.TLSState.Version trans.hash, trans.bodyhash = getHashes(trans) transid, err := handleMessage(prefix, trans, logf) // errors when handling a message always force // a tempfail regardless of how we're // configured. switch { case err != nil: convo.Tempfail() gotsomewhere = true case decider(pMessage, evt, c, convo, transid): // do nothing, already handled default: if minphase == "accepted" { gotsomewhere = true } doAccept(convo, c, transid) } case smtpd.TLSERROR: // any TLS error means we'll avoid offering TLS // to this source IP for a while. notls.Add(trans.rip, tlsTimeout) sesscounts = false } if evt.What == smtpd.DONE || evt.What == smtpd.ABORT { break } } // if the client did not issue any successful meaningful commands, // remember this. we squelch people who yak too long. // Once people are yakkers we don't count their continued failure // to do anything against them. // And we have to have good rules to start with because duh. switch { case !gotsomewhere && sesscounts: cnt = yakkers.Add(trans.rip, yakTimeout) // See if this transaction has pushed the client over the // edge to becoming a yakker. If so, report it to the SMTP // log. if cnt >= yakCount { writeLog(logger, "! %s added as a yakker at hit %d\n", trans.rip, cnt) } case yakCount > 0 && gotsomewhere: yakkers.Del(trans.rip) } }