Files
Miccah ddc81bd7c1 [THOG-162] Implement JDBC verification for select drivers (#792)
* [THOG-162] Implement JDBC verification for select drivers

Also includes integration tests for postgres and mysql via docker. To
run, execute the following (untested what will happen if the docker
images aren't installed):

go test -tags=detectors,integration ./pkg/detectors/jdbc

* Make jdbc regex a bit more strict

* Surface the context to allow the caller to set a timeout
2022-09-21 17:50:48 +02:00

67 lines
1.4 KiB
Go

package jdbc
import (
"context"
"errors"
"strings"
_ "github.com/go-sql-driver/mysql"
)
type mysqlJDBC struct {
conn string
userPass string
host string
database string
params string
}
func (s *mysqlJDBC) ping(ctx context.Context) bool {
if ping(ctx, "mysql", s.conn) {
return true
}
// try building connection string (should be same as s.conn though)
if ping(ctx, "mysql", s.build()) {
return true
}
// try removing database
s.database = ""
return ping(ctx, "mysql", s.build())
}
func (s *mysqlJDBC) build() string {
conn := s.host + "/" + s.database
if s.userPass != "" {
conn = s.userPass + "@" + conn
}
if s.params != "" {
conn = conn + "?" + s.params
}
return conn
}
func parseMySQL(subname string) (jdbc, error) {
// expected form: [subprotocol:]//[user:password@]HOST[/DB][?key=val[&key=val]]
hostAndDB, params, _ := strings.Cut(subname, "?")
if !strings.HasPrefix(hostAndDB, "//") {
return nil, errors.New("expected host to start with //")
}
userPassAndHostAndDB := strings.TrimPrefix(hostAndDB, "//")
userPass, hostAndDB, found := strings.Cut(userPassAndHostAndDB, "@")
if !found {
hostAndDB = userPass
userPass = ""
}
host, database, found := strings.Cut(hostAndDB, "/")
if !found {
return nil, errors.New("expected host and database to be separated by /")
}
return &mysqlJDBC{
conn: subname[2:],
userPass: userPass,
host: host,
database: database,
params: params,
}, nil
}