func appendSSLConnectionStringParam(logger lager.Logger, driverName, databaseConnectionString, sqlCACertFile string) string { switch driverName { case "mysql": if sqlCACertFile != "" { certBytes, err := ioutil.ReadFile(sqlCACertFile) if err != nil { logger.Fatal("failed-to-read-sql-ca-file", err) } caCertPool := x509.NewCertPool() if ok := caCertPool.AppendCertsFromPEM(certBytes); !ok { logger.Fatal("failed-to-parse-sql-ca", err) } tlsConfig := &tls.Config{ InsecureSkipVerify: false, RootCAs: caCertPool, } mysql.RegisterTLSConfig("bbs-tls", tlsConfig) databaseConnectionString = fmt.Sprintf("%s?tls=bbs-tls", databaseConnectionString) } case "postgres": if sqlCACertFile == "" { databaseConnectionString = fmt.Sprintf("%s?sslmode=disable", databaseConnectionString) } else { databaseConnectionString = fmt.Sprintf("%s?sslmode=verify-ca&sslrootcert=%s", databaseConnectionString, sqlCACertFile) } } return databaseConnectionString }
func getEngine() (*xorm.Engine, error) { LoadConfig() cnnstr := "" switch DbCfg.Type { case "mysql": protocol := "tcp" if strings.HasPrefix(DbCfg.Host, "/") { protocol = "unix" } cnnstr = fmt.Sprintf("%s:%s@%s(%s)/%s?charset=utf8", DbCfg.User, DbCfg.Pwd, protocol, DbCfg.Host, DbCfg.Name) if mysqlConfig.SslMode == "true" || mysqlConfig.SslMode == "skip-verify" { tlsCert, err := makeCert("custom", mysqlConfig) if err != nil { return nil, err } mysql.RegisterTLSConfig("custom", tlsCert) cnnstr += "&tls=custom" } case "postgres": var host, port = "127.0.0.1", "5432" fields := strings.Split(DbCfg.Host, ":") if len(fields) > 0 && len(strings.TrimSpace(fields[0])) > 0 { host = fields[0] } if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 { port = fields[1] } if DbCfg.Pwd == "" { DbCfg.Pwd = "''" } if DbCfg.User == "" { DbCfg.User = "******" } cnnstr = fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s", DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode) case "sqlite3": if !filepath.IsAbs(DbCfg.Path) { DbCfg.Path = filepath.Join(setting.DataPath, DbCfg.Path) } os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm) cnnstr = "file:" + DbCfg.Path + "?cache=shared&mode=rwc&_loc=Local" default: return nil, fmt.Errorf("Unknown database type: %s", DbCfg.Type) } log.Info("Database: %v", DbCfg.Type) return xorm.NewEngine(DbCfg.Type, cnnstr) }
func (driver *Driver) Initialize(url string) error { urlWithoutScheme := strings.SplitN(url, "mysql://", 2) if len(urlWithoutScheme) != 2 { return errors.New("invalid mysql:// scheme") } // check if env vars vor mysql ssl connection are set and if yes use them if os.Getenv("MYSQL_SERVER_CA") != "" && os.Getenv("MYSQL_CLIENT_KEY") != "" && os.Getenv("MYSQL_CLIENT_CERT") != "" { rootCertPool := x509.NewCertPool() pem, err := ioutil.ReadFile(os.Getenv("MYSQL_SERVER_CA")) if err != nil { return err } if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { return errors.New("Failed to append PEM") } clientCert := make([]tls.Certificate, 0, 1) certs, err := tls.LoadX509KeyPair(os.Getenv("MYSQL_CLIENT_CERT"), os.Getenv("MYSQL_CLIENT_KEY")) if err != nil { return err } clientCert = append(clientCert, certs) mysql.RegisterTLSConfig("custom", &tls.Config{ RootCAs: rootCertPool, Certificates: clientCert, InsecureSkipVerify: true, }) urlWithoutScheme[1] += "&tls=custom" } db, err := sql.Open("mysql", urlWithoutScheme[1]) if err != nil { return err } if err := db.Ping(); err != nil { return err } driver.db = db if err := driver.ensureVersionTableExists(); err != nil { return err } return nil }
// ConnectToMySQLDatabase generates a secure or insecure TCP MySQL database connection on port 3306 func ConnectToMySQLDatabase(username, password, database, server string, tlsInfo *TLSCertificates, secure bool) (*sql.DB, error) { if secure { // Create a cert pool rootCertPool := x509.NewCertPool() // Load the Certificate Authority cert pem, err := ioutil.ReadFile(tlsInfo.BasePath + tlsInfo.CACertRelativePath) if err != nil { return nil, fmt.Errorf("Failed to open ca cert: %s", err.Error()) } // Append the CA cert to the cert pool ok := rootCertPool.AppendCertsFromPEM(pem) if !ok { return nil, fmt.Errorf("Failed to append Certs from PEM.") } // Load the Client Certificate and Key clientCert := make([]tls.Certificate, 0, 1) certs, err := tls.LoadX509KeyPair(tlsInfo.BasePath+tlsInfo.ClientCertRelativePath, tlsInfo.BasePath+tlsInfo.ClientKeyRelativePath) if err != nil { return nil, fmt.Errorf("Failed to load x509 client cert and key: %s", err.Error()) } clientCert = append(clientCert, certs) // Register the TLS configuration with MySQL mysql.RegisterTLSConfig("custom", &tls.Config{ RootCAs: rootCertPool, Certificates: clientCert, }) // Open the connection url := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s?tls=skip-verify", username, password, server, database) db, err := sql.Open("mysql", url) if err != nil { return nil, fmt.Errorf("Couldn't connect to database: %s", err.Error()) } return db, nil } url := fmt.Sprintf("%s:%s@tcp(%s:3306)/%s", username, password, server, database) db, err := sql.Open("mysql", url) if err != nil { return nil, fmt.Errorf("Couldn't connect to database: %s", err.Error()) } return db, nil }
// Create a TLS configuration from the config supplied CA, Certificate, and Private key. // Register the TLS config with the mysql drivers as the "orchestrator" config // Modify the supplied URI to call the TLS config func SetupMySQLOrchestratorTLS(uri string) (string, error) { if !orchestratorTLSConfigured { tlsConfig, err := ssl.NewTLSConfig(config.Config.MySQLOrchestratorSSLCAFile, true) if err != nil { return "", log.Fatalf("Can't create TLS configuration for Orchestrator connection %s: %s", uri, err) } tlsConfig.InsecureSkipVerify = config.Config.MySQLOrchestratorSSLSkipVerify if err = ssl.AppendKeyPair(tlsConfig, config.Config.MySQLOrchestratorSSLCertFile, config.Config.MySQLOrchestratorSSLPrivateKeyFile); err != nil { return "", log.Fatalf("Can't setup TLS key pairs for %s: %s", uri, err) } if err = mysql.RegisterTLSConfig("orchestrator", tlsConfig); err != nil { return "", log.Fatalf("Can't register mysql TLS config for orchestrator: %s", err) } orchestratorTLSConfigured = true } return fmt.Sprintf("%s&tls=orchestrator", uri), nil }
// Create a TLS configuration from the config supplied CA, Certificate, and Private key. // Register the TLS config with the mysql drivers as the "topology" config // Modify the supplied URI to call the TLS config // TODO: Way to have password mixed with TLS for various nodes in the topology. Currently everything is TLS or everything is password func SetupMySQLTopologyTLS(uri string) (string, error) { if !topologyTLSConfigured { tlsConfig, err := ssl.NewTLSConfig(config.Config.MySQLTopologySSLCAFile, !config.Config.MySQLTopologySSLSkipVerify) // Drop to TLS 1.0 for talking to MySQL tlsConfig.MinVersion = tls.VersionTLS10 if err != nil { return "", log.Fatalf("Can't create TLS configuration for Topology connection %s: %s", uri, err) } tlsConfig.InsecureSkipVerify = config.Config.MySQLTopologySSLSkipVerify if err = ssl.AppendKeyPair(tlsConfig, config.Config.MySQLTopologySSLCertFile, config.Config.MySQLTopologySSLPrivateKeyFile); err != nil { return "", log.Fatalf("Can't setup TLS key pairs for %s: %s", uri, err) } if err = mysql.RegisterTLSConfig("topology", tlsConfig); err != nil { return "", log.Fatalf("Can't register mysql TLS config for topology: %s", err) } topologyTLSConfigured = true } return fmt.Sprintf("%s&tls=topology", uri), nil }
// Establish a TLS connection with a given CA certificate // Register a tsl.Config associted with the same key as the dns param from sql.Open // foo:bar@tcp(127.0.0.1:3306)/dbname?tls=default func setupMySQLTLSConfig(tlsCaFile string) error { rootCertPool := x509.NewCertPool() pem, err := ioutil.ReadFile(tlsCaFile) if err != nil { return err } if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { return err } err = mysql.RegisterTLSConfig(mysqlTLSKey, &tls.Config{ RootCAs: rootCertPool, }) if err != nil { return err } return nil }
func Query(host string, cxn Sqlcxn, wg *sync.WaitGroup) { defer wg.Done() var dsn string dsn = cxn.Username + ":" + cxn.Password + "@tcp(" + host + ":" + strconv.Itoa(cxn.Port) + ")/" if cxn.MultiStatements == true { dsn += "?multiStatements=true" } else { dsn += "?multiStatements=false" } if cxn.TlsConfig.Certificates != nil { mysql.RegisterTLSConfig("omnisql", &cxn.TlsConfig) dsn += "&tls=omnisql" } if cxn.ConnectTimeout <= 0 { dsn += "&timeout=2" } else { dsn += "&timeout=" + strconv.Itoa(cxn.ConnectTimeout) + "s" } dsn += "&readTimeout=" + strconv.Itoa(cxn.ReadTimeout) + "s" dsn += "&writeTimeout=" + strconv.Itoa(cxn.WriteTimeout) + "s" // SSL Support if cxn.SslCa != "" || cxn.SslCaPath != "" || cxn.SslCert != "" || cxn.SslCipher != "" || cxn.SslKey != "" { dsn += "&tls=omnisql" } db, err := sql.Open("mysql", dsn) if err != nil { log.Println(host, "\t", err.Error()) return } defer db.Close() // Execute the query rows, err := db.Query(cxn.Query) if err != nil { log.Println("WARNING: Could not connect to '" + host + "': Unknown MySQL server host '" + host + "'") return } // Get column names columns, err := rows.Columns() if err != nil { log.Println(host, "\t", err.Error()) return } // Make a slice for the values values := make([]sql.RawBytes, len(columns)) // rows.Scan wants '[]interface{}' as an argument, so we must copy the // references into such a slice // See http://code.google.com/p/go-wiki/wiki/InterfaceSlice for details scanArgs := make([]interface{}, len(values)) for i := range values { scanArgs[i] = &values[i] } // Fetch rows for rows.Next() { var res string res += host // get RawBytes from data err = rows.Scan(scanArgs...) if err != nil { log.Println(host, "\t", err.Error()) return } // Now do something with the data. // Here we just print each column as a string. for _, col := range values { // Here we can check if the value is nil (NULL value) if col == nil { res += "\tNULL" } else { res += "\t" res += string(col) } } fmt.Println(res) } if err = rows.Err(); err != nil { log.Println(host, "\t", err.Error()) return } return }
func main() { var ( dbUser = flag.String("db-user", "auth", "Auth database username.") dbPasswd = flag.String("db-pass", "", "Auth database password.") dbHost = flag.String("db-host", "", "Auth database host.") dbPort = flag.String("db-port", "3306", "Auth database port.") dbServerName = flag.String("db-server-name", "", "Auth database server name.") dbServerCACert = flag.String("db-server-ca-cert", "/etc/auth/db-server-ca.pem", "Database server ca certificate") dbClientCert = flag.String("db-client-cert", "/etc/auth/db-client-cert.pem", "Database client certificate.") dbClientKey = flag.String("db-client-key", "/etc/auth/db-client-key.pem", "Database client key.") debugListenAddr = flag.String("debug-listen-addr", "127.0.0.1:7801", "HTTP listen address.") listenAddr = flag.String("listen-addr", "127.0.0.1:7800", "HTTP listen address.") tlsCert = flag.String("tls-cert", "/etc/auth/cert.pem", "TLS server certificate.") tlsKey = flag.String("tls-key", "/etc/auth/key.pem", "TLS server key.") jwtPrivateKey = flag.String("jwt-private-key", "/etc/auth/jwt-key.pem", "The RSA private key to use for signing JWTs") ) flag.Parse() var err error log.Println("Auth service starting...") certPool := x509.NewCertPool() pem, err := ioutil.ReadFile(*dbServerCACert) if err != nil { log.Fatal(err) } if ok := certPool.AppendCertsFromPEM(pem); !ok { log.Fatal("Failed to append PEM.") } clientCert := make([]tls.Certificate, 0, 1) certs, err := tls.LoadX509KeyPair(*dbClientCert, *dbClientKey) if err != nil { log.Fatal(err) } clientCert = append(clientCert, certs) mysql.RegisterTLSConfig("custom", &tls.Config{ ServerName: *dbServerName, RootCAs: certPool, Certificates: clientCert, }) dbAddr := net.JoinHostPort(*dbHost, *dbPort) dbConfig := mysql.Config{ User: *dbUser, Passwd: *dbPasswd, Net: "tcp", Addr: dbAddr, DBName: "auth", TLSConfig: "custom", } for { db, err = sql.Open("mysql", dbConfig.FormatDSN()) if err != nil { goto dberror } err = db.Ping() if err != nil { goto dberror } break dberror: log.Println(err) log.Println("error connecting to the auth database, retrying in 5 secs.") time.Sleep(5 * time.Second) } ta, err := credentials.NewServerTLSFromFile(*tlsCert, *tlsKey) if err != nil { log.Fatal(err) } gs := grpc.NewServer(grpc.Creds(ta)) as, err := NewAuthServer(*jwtPrivateKey) if err != nil { log.Fatal(err) } pb.RegisterAuthServer(gs, as) hs := health.NewHealthServer() hs.SetServingStatus("grpc.health.v1.authservice", 1) healthpb.RegisterHealthServer(gs, hs) ln, err := net.Listen("tcp", *listenAddr) if err != nil { log.Fatal(err) } go gs.Serve(ln) trace.AuthRequest = func(req *http.Request) (any, sensitive bool) { return true, true } log.Println("Auth service started successfully.") log.Fatal(http.ListenAndServe(*debugListenAddr, nil)) }
func main() { var ( email = flag.String("e", "", "The user email address.") username = flag.String("u", "", "The username.") isAdmin = flag.Bool("a", false, "Enable the admin flag.") ) flag.Parse() fmt.Println("enter password:"******"marshaling error: ", err) } certPool := x509.NewCertPool() pem, err := ioutil.ReadFile("/etc/auth/server-ca.pem") if err != nil { log.Fatal(err) } if ok := certPool.AppendCertsFromPEM(pem); !ok { log.Fatal("Failed to append PEM.") } clientCert := make([]tls.Certificate, 0, 1) certs, err := tls.LoadX509KeyPair("/etc/auth/client-cert.pem", "/etc/auth/client-key.pem") if err != nil { log.Fatal(err) } clientCert = append(clientCert, certs) mysql.RegisterTLSConfig("custom", &tls.Config{ ServerName: "hightowerlabs:database", RootCAs: certPool, Certificates: clientCert, }) db, err := sql.Open("mysql", "auth:grpcauth@tcp(104.196.125.211:3306)/auth?tls=custom") if err != nil { log.Fatal(err) } _, err = db.Exec("INSERT INTO users (username, proto) VALUES (?, ?)", user.Username, data) if err != nil { log.Fatal(err) } }
func main() { flag.Parse() if *dump == "" { log.Fatalf("no -dump file specified") } if *enableSsl { rootCertPool := x509.NewCertPool() pem, err := ioutil.ReadFile(*sslCa) if err != nil { log.Fatalln("ioutil.Readline:", err) } if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { log.Fatal("Failed to append CA certificate PEM.") } clientCert := []tls.Certificate{} certs, err := tls.LoadX509KeyPair(*sslCert, *sslKey) if err != nil { log.Fatalln("tls.LoadX509KeyPair:", err) } clientCert = append(clientCert, certs) mysql.RegisterTLSConfig("custom", &tls.Config{ RootCAs: rootCertPool, Certificates: clientCert, ServerName: *serverName, }) } db, err := sql.Open("mysql", *dsn) if err != nil { log.Fatalln("sql.Open:", err) } defer db.Close() f, err := os.Open(*dump) if err != nil { log.Fatalf("os.Open: %v", err) } defer f.Close() dumpInfo, err := f.Stat() if err != nil { log.Fatalf("Stat: %v", err) } size := dumpInfo.Size() logFilename := fmt.Sprintf("%s.log", dumpInfo.Name()) pos, err := recover(logFilename) if err != nil { log.Fatalf("recover from log: %v", err) } if pos != 0 { log.Printf("seeking to %d in %q", pos, f.Name()) if _, err = f.Seek(pos, os.SEEK_SET); err != nil { log.Fatalf("Seek: %v", err) } } logFile, err := os.OpenFile(logFilename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Fatalf("os.OpenFile: %v", err) } defer logFile.Close() // buf[i:j] are the bytes that have been read from f but not // yet replayed. k indicates up to where we read in a // multi-line query. buf := make([]byte, 1024*1024) i, j, k, readErr := 0, 0, 0, error(nil) for { if p := bytes.IndexByte(buf[k:j], '\n'); p >= 0 { k += p + 1 // The +1 is for the trailing '\n'. pos += int64(p + 1) if replay(db, buf[i:k-1], pos, size) { i = k err = save(logFile, pos) if err != nil { log.Fatalf("Error saving to log: %v", err) } } continue } if readErr != nil { if readErr == io.EOF { if i != j { log.Println(i, j) log.Fatalf(`The contents of %q do not end with a "\n"`, *dump) } return } log.Fatal(readErr) } // First, make sure at least half of the buffer is empty. If we can do // that by moving the contents of buf[i:j] to the start of the existing // buffer, that's great. Otherwise, allocate a bigger buffer. newBuf := buf if j-i > len(buf)/2 { newBuf = make([]byte, len(buf)*2) } i, j, k = 0, copy(newBuf, buf[i:j]), k-i buf = newBuf // Read some more bytes. var n int n, readErr = f.Read(buf[j:]) j += n } }
func main() { flag.Parse() if *dump == "" { log.Fatalf("no -dump file specified") } var finalDsn = *dsn if *enableSsl { pem, err := ioutil.ReadFile(*sslCa) if err != nil { log.Fatalln("ioutil.Readline:", err) } rootCertPool := x509.NewCertPool() if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { log.Fatal("Failed to append CA certificate PEM.") } clientCert := []tls.Certificate{} certs, err := tls.LoadX509KeyPair(*sslCert, *sslKey) if err != nil { log.Fatalln("tls.LoadX509KeyPair:", err) } clientCert = append(clientCert, certs) const customTLSName = "custom" tlserr := mysql.RegisterTLSConfig(customTLSName, &tls.Config{ RootCAs: rootCertPool, Certificates: clientCert, ServerName: *serverName, }) if tlserr != nil { log.Fatalln("mysql.RegisterTLSConfig:", tlserr) } finalDsn = strings.Join([]string{finalDsn, "?tls=", customTLSName}, "") } if *prompt { // DSN strings look like: // user:password@tcp(0.0.0.0:3306)/ // With this flag the user can avoid typing their password: // user@tcp(0.0.0.0:3306)/ // Save text before ':' and after '@' so we can insert the password // to create a proper DSN string. dsnRegex := regexp.MustCompile(`(\w*):?\w*(@.+)`) matches := dsnRegex.FindStringSubmatch(finalDsn) if matches == nil { fmt.Print("Incorrect format for dsn. Usage:\n") flag.PrintDefaults() os.Exit(1) } fmt.Print("Enter password: "******"Error reading password:"******"\n") // Insert password into the connection string. finalDsn = strings.Join([]string{matches[1], ":", string(password), matches[2]}, "") } db, err := sql.Open("mysql", finalDsn) if err != nil { log.Fatalln("sql.Open:", err) } defer db.Close() f, err := os.Open(*dump) if err != nil { log.Fatalf("os.Open: %v", err) } defer f.Close() dumpInfo, err := f.Stat() if err != nil { log.Fatalf("Stat: %v", err) } size := dumpInfo.Size() logFilename := fmt.Sprintf("%s.log", dumpInfo.Name()) pos, err := recover(logFilename) if err != nil { log.Fatalf("recover from log: %v", err) } if pos != 0 { log.Printf("seeking to %d in %q", pos, f.Name()) if _, err = f.Seek(pos, os.SEEK_SET); err != nil { log.Fatalf("Seek: %v", err) } } logFile, err := os.OpenFile(logFilename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Fatalf("os.OpenFile: %v", err) } defer logFile.Close() // buf[i:j] are the bytes that have been read from f but not // yet replayed. k indicates up to where we read in a // multi-line query. buf := make([]byte, 1024*1024) i, j, k, readErr := 0, 0, 0, error(nil) for { if p := bytes.IndexByte(buf[k:j], '\n'); p >= 0 { k += p + 1 // The +1 is for the trailing '\n'. pos += int64(p + 1) if replay(db, buf[i:k-1], pos, size) { i = k err = save(logFile, pos) if err != nil { log.Fatalf("Error saving to log: %v", err) } } continue } if readErr != nil { if readErr == io.EOF { if i != j { log.Println(i, j) log.Fatalf(`The contents of %q do not end with a "\n"`, *dump) } return } log.Fatal(readErr) } // First, make sure at least half of the buffer is empty. If we can do // that by moving the contents of buf[i:j] to the start of the existing // buffer, that's great. Otherwise, allocate a bigger buffer. newBuf := buf if j-i > len(buf)/2 { newBuf = make([]byte, len(buf)*2) } i, j, k = 0, copy(newBuf, buf[i:j]), k-i buf = newBuf // Read some more bytes. var n int n, readErr = f.Read(buf[j:]) j += n } }