From 883523c25f3a90c65cc0acdd152d68f3ae1a7504 Mon Sep 17 00:00:00 2001 From: Javier Marcos Date: Mon, 23 Mar 2020 18:56:59 -0700 Subject: [PATCH 1/3] Refactor for TLS handlers --- admin/handlers/go.mod | 3 + admin/handlers/handlers.go | 10 + admin/main.go | 5 +- deploy/provision.sh | 13 +- go.mod | 3 + logging/db.go | 29 +- logging/dispatch.go | 66 ++++ logging/logging.go | 8 +- logging/process.go | 88 +++++ logging/utils.go | 14 + nodes/go.sum | 123 ++++++ nodes/metadata.go | 31 ++ nodes/nodes.go | 44 +-- tls/{carving.go => handlers/carves.go} | 36 +- tls/handlers/go.mod | 5 + tls/handlers/go.sum | 6 + tls/{handlers-tls.go => handlers/handlers.go} | 366 +++++++++++------- tls/handlers/utils.go | 107 +++++ tls/logs.go | 137 ------- tls/main.go | 129 +++--- 20 files changed, 834 insertions(+), 389 deletions(-) create mode 100644 admin/handlers/go.mod create mode 100644 admin/handlers/handlers.go create mode 100644 logging/dispatch.go create mode 100644 logging/process.go create mode 100644 logging/utils.go create mode 100644 nodes/go.sum create mode 100644 nodes/metadata.go rename tls/{carving.go => handlers/carves.go} (58%) create mode 100644 tls/handlers/go.mod create mode 100644 tls/handlers/go.sum rename tls/{handlers-tls.go => handlers/handlers.go} (58%) create mode 100644 tls/handlers/utils.go delete mode 100644 tls/logs.go diff --git a/admin/handlers/go.mod b/admin/handlers/go.mod new file mode 100644 index 00000000..b090f2c7 --- /dev/null +++ b/admin/handlers/go.mod @@ -0,0 +1,3 @@ +module github.com/javuto/osctrl/admin/handlers + +go 1.12 diff --git a/admin/handlers/handlers.go b/admin/handlers/handlers.go new file mode 100644 index 00000000..85a1e20f --- /dev/null +++ b/admin/handlers/handlers.go @@ -0,0 +1,10 @@ +package handlers + +const ( + metricJSONReq = "admin-json-req" + metricJSONErr = "admin-json-err" + metricJSONOK = "admin-json-ok" + metricHealthReq = "health-req" + metricHealthOK = "health-ok" +) + diff --git a/admin/main.go b/admin/main.go index 591145b2..e2e6ce14 100644 --- a/admin/main.go +++ b/admin/main.go @@ -256,8 +256,6 @@ func main() { // Initialize service settings log.Println("Loading service settings") loadingSettings() - // multiple listeners channel - finish := make(chan bool) // Start SAML Middleware if we are using SAML if adminConfig.Auth == settings.AuthSAML { @@ -416,6 +414,9 @@ func main() { } }() + // multiple listeners channel + finish := make(chan bool) + // Launch HTTP server for admin go func() { serviceAdmin := adminConfig.Listener + ":" + adminConfig.Port diff --git a/deploy/provision.sh b/deploy/provision.sh index 76a21c26..f31df5cd 100755 --- a/deploy/provision.sh +++ b/deploy/provision.sh @@ -631,8 +631,14 @@ DEST="$DEST_PATH" make install_cli # If we are in dev, create environment and enroll host if [[ "$MODE" == "dev" ]]; then - log "Creating environment for dev" __db_conf="$DEST_PATH/config/$DB_CONF" + + # Create admin user + log "Creating admin user" + "$DEST_PATH"/osctrl-cli -D "$__db_conf" user add -u "$_ADMIN_USER" -p "$_ADMIN_PASS" -a -n Admin + + # Create environment for dev + log "Creating environment for dev" __osquery_dev="$SOURCE_PATH/deploy/osquery/osquery-dev.json" __osctrl_crt="/etc/nginx/certs/osctrl.crt" "$DEST_PATH"/osctrl-cli -D "$__db_conf" environment add -n "dev" -host "$_T_HOST" -conf "$__osquery_dev" -crt "$__osctrl_crt" @@ -649,16 +655,13 @@ if [[ "$MODE" == "dev" ]]; then sleep 1 done + # Enroll host in environment if [[ "$ENROLL" == true ]]; then log "Adding host in dev environment" eval $( "$DEST_PATH"/osctrl-cli -D "$__db_conf" environment quick-add -n "dev" ) fi fi -# Create admin user -log "Creating admin user" -"$DEST_PATH"/osctrl-cli -D "$__db_conf" user add -u "$_ADMIN_USER" -p "$_ADMIN_PASS" -a -n Admin - # Ascii art is always appreciated if [[ "$DISTRO" == "ubuntu" ]]; then set_motd_ubuntu "$SOURCE_PATH/deploy/motd-osctrl.sh" diff --git a/go.mod b/go.mod index 378ccacd..7a6b8628 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/jmpsec/osctrl/nodes v0.2.1 github.com/jmpsec/osctrl/queries v0.2.1 github.com/jmpsec/osctrl/settings v0.2.1 + github.com/jmpsec/osctrl/tls/handlers v0.2.1 github.com/jmpsec/osctrl/types v0.2.1 github.com/jmpsec/osctrl/users v0.2.1 github.com/jmpsec/osctrl/utils v0.2.1 @@ -51,3 +52,5 @@ replace github.com/jmpsec/osctrl/users => ./users replace github.com/jmpsec/osctrl/utils => ./utils replace github.com/jmpsec/osctrl/logging => ./logging + +replace github.com/jmpsec/osctrl/tls/handlers => ./tls/handlers diff --git a/logging/db.go b/logging/db.go index bf6c9026..fc322363 100644 --- a/logging/db.go +++ b/logging/db.go @@ -7,8 +7,8 @@ import ( "github.com/jinzhu/gorm" "github.com/jmpsec/osctrl/backend" - "github.com/jmpsec/osctrl/types" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/types" ) const ( @@ -82,19 +82,28 @@ func CreateLoggerDB() (*LoggerDB, error) { func (logDB *LoggerDB) Settings(mgr *settings.Settings) { log.Printf("Setting DB logging settings\n") // Setting link for on-demand queries - v := settings.QueryLink - if err := mgr.SetString(v, settings.ServiceAdmin, settings.QueryResultLink, false); err != nil { - log.Printf("Error setting %s with %s - %v", v, settings.QueryResultLink, err) + if !mgr.IsValue(settings.ServiceAdmin, settings.QueryResultLink) { + if err := mgr.NewStringValue(settings.ServiceAdmin, settings.QueryResultLink, settings.QueryLink); err != nil { + log.Fatalf("Failed to add %s to settings: %v", settings.QueryResultLink, err) + } + } else if err := mgr.SetString(settings.QueryLink, settings.ServiceAdmin, settings.QueryResultLink, false); err != nil { + log.Printf("Error setting %s with %s - %v", settings.QueryResultLink, settings.QueryLink, err) } - v = settings.StatusLink // Setting link for status logs - if err := mgr.SetString(v, settings.ServiceAdmin, settings.StatusLogsLink, false); err != nil { - log.Printf("Error setting %s with %s - %v", v, settings.StatusLogsLink, err) + if !mgr.IsValue(settings.ServiceAdmin, settings.StatusLogsLink) { + if err := mgr.NewStringValue(settings.ServiceAdmin, settings.StatusLogsLink, settings.StatusLink); err != nil { + log.Fatalf("Failed to add %s to settings: %v", settings.DebugHTTP, err) + } + } else if err := mgr.SetString(settings.StatusLink, settings.ServiceAdmin, settings.StatusLogsLink, false); err != nil { + log.Printf("Error setting %s with %s - %v", settings.StatusLogsLink, settings.StatusLink, err) } - v = settings.ResultsLink // Setting link for result logs - if err := mgr.SetString(v, settings.ServiceAdmin, settings.ResultLogsLink, false); err != nil { - log.Printf("Error setting %s with %s - %v", v, settings.ResultLogsLink, err) + if !mgr.IsValue(settings.ServiceAdmin, settings.ResultLogsLink) { + if err := mgr.NewStringValue(settings.ServiceAdmin, settings.ResultLogsLink, settings.ResultsLink); err != nil { + log.Fatalf("Failed to add %s to settings: %v", settings.DebugHTTP, err) + } + } else if err := mgr.SetString(settings.ResultsLink, settings.ServiceAdmin, settings.ResultLogsLink, false); err != nil { + log.Printf("Error setting %s with %s - %v", settings.ResultLogsLink, settings.ResultsLink, err) } } diff --git a/logging/dispatch.go b/logging/dispatch.go new file mode 100644 index 00000000..e257a79f --- /dev/null +++ b/logging/dispatch.go @@ -0,0 +1,66 @@ +package logging + +import ( + "encoding/json" + "log" + + "github.com/jmpsec/osctrl/nodes" + "github.com/jmpsec/osctrl/types" +) + +// DispatchLogs - Helper to dispatch logs +func (l *LoggerTLS) DispatchLogs(data []byte, uuid, logType, environment string, metadata nodes.NodeMetadata, debug bool) { + // Use metadata to update record + if err := l.Nodes.UpdateMetadataByUUID(uuid, metadata); err != nil { + log.Printf("error updating metadata %s", err) + } + // Send data to storage + // FIXME allow multiple types of logging + if debug { + log.Printf("dispatching logs to %s", l.Logging) + } + l.Log( + logType, + data, + environment, + uuid, + debug) + // Refresh last logging request + if logType == types.StatusLog { + err := l.Nodes.RefreshLastStatus(uuid) + if err != nil { + log.Printf("error refreshing last status %v", err) + } + } + if logType == types.ResultLog { + if err := l.Nodes.RefreshLastResult(uuid); err != nil { + log.Printf("error refreshing last result %v", err) + } + } +} + +// DispatchQueries - Helper to dispatch queries +func (l *LoggerTLS) DispatchQueries(queryData types.QueryWriteData, node nodes.OsqueryNode, debug bool) { + // Prepare data to send + data, err := json.Marshal(queryData) + if err != nil { + log.Printf("error preparing data %v", err) + } + // Refresh last query write request + if err := l.Nodes.RefreshLastQueryWrite(node.UUID); err != nil { + log.Printf("error refreshing last query write %v", err) + } + // Send data to storage + // FIXME allow multiple types of logging + if debug { + log.Printf("dispatching queries to %s", l.Logging) + } + l.QueryLog( + types.QueryLog, + data, + node.Environment, + node.UUID, + queryData.Name, + queryData.Status, + debug) +} diff --git a/logging/logging.go b/logging/logging.go index ac2effed..8b5dfec3 100644 --- a/logging/logging.go +++ b/logging/logging.go @@ -1,6 +1,8 @@ package logging import ( + "github.com/jmpsec/osctrl/nodes" + "github.com/jmpsec/osctrl/queries" "github.com/jmpsec/osctrl/settings" ) @@ -10,15 +12,19 @@ type LoggerTLS struct { Graylog *LoggerGraylog Splunk *LoggerSplunk Logging string + Nodes *nodes.NodeManager + Queries *queries.Queries } // CreateLoggerTLS to instantiate a new logger for the TLS endpoint -func CreateLoggerTLS(logging string, mgr *settings.Settings) (*LoggerTLS, error) { +func CreateLoggerTLS(logging string, mgr *settings.Settings, nodes *nodes.NodeManager, queries *queries.Queries) (*LoggerTLS, error) { l := &LoggerTLS{ DB: &LoggerDB{}, Splunk: &LoggerSplunk{}, Logging: logging, Graylog: &LoggerGraylog{}, + Nodes: nodes, + Queries: queries, } switch logging { case settings.LoggingSplunk: diff --git a/logging/process.go b/logging/process.go new file mode 100644 index 00000000..a7e766b8 --- /dev/null +++ b/logging/process.go @@ -0,0 +1,88 @@ +package logging + +import ( + "encoding/json" + "log" + + "github.com/jmpsec/osctrl/nodes" + "github.com/jmpsec/osctrl/types" +) + +// ProcessLogs - Helper to process logs +func (l *LoggerTLS) ProcessLogs(data json.RawMessage, logType, environment, ipaddress string, debug bool) { + // Parse log to extract metadata + var logs []types.LogGenericData + err := json.Unmarshal(data, &logs) + if err != nil { + // FIXME metrics for this + log.Printf("error parsing log %s %v", string(data), err) + } + if debug { + log.Printf("parsing logs for metadata in %s:%s", logType, environment) + } + // Iterate through received messages to extract metadata + var uuids, hosts, names, users, osqueryusers, hashes, dhashes, osqueryversions []string + for _, l := range logs { + uuids = append(uuids, l.HostIdentifier) + hosts = append(hosts, l.Decorations.Hostname) + names = append(names, l.Decorations.LocalHostname) + users = append(users, l.Decorations.Username) + osqueryusers = append(osqueryusers, l.Decorations.OsqueryUser) + hashes = append(hashes, l.Decorations.ConfigHash) + dhashes = append(dhashes, l.Decorations.DaemonHash) + osqueryversions = append(osqueryversions, l.Version) + } + if debug { + log.Printf("metadata and dispatch for %s", uniq(uuids)[0]) + } + // FIXME it only uses the first element from the []string that uniq returns + metadata := nodes.NodeMetadata{ + IPAddress: ipaddress, + Username: uniq(users)[0], + OsqueryUser: uniq(osqueryusers)[0], + Hostname: uniq(hosts)[0], + Localname: uniq(names)[0], + ConfigHash: uniq(hashes)[0], + DaemonHash: uniq(dhashes)[0], + OsqueryVersion: uniq(osqueryversions)[0], + } + // Dispatch logs and update metadata + l.DispatchLogs(data, uniq(uuids)[0], logType, environment, metadata, debug) +} + +// ProcessLogQueryResult - Helper to process on-demand query result logs +func (l *LoggerTLS) ProcessLogQueryResult(queries types.QueryWriteQueries, statuses types.QueryWriteStatuses, nodeKey string, environment string, debug bool) { + // Retrieve node + node, err := l.Nodes.GetByKey(nodeKey) + if err != nil { + log.Printf("error retrieving node %s", err) + } + // Tap into results so we can update internal metrics + for q, r := range queries { + // Dispatch query name, result and status + d := types.QueryWriteData{ + Name: q, + Result: r, + Status: statuses[q], + } + go l.DispatchQueries(d, node, debug) + // Update internal metrics per query + var err error + if statuses[q] != 0 { + err = l.Queries.IncError(q) + } else { + err = l.Queries.IncExecution(q) + } + if err != nil { + log.Printf("error updating query %s", err) + } + // Add a record for this query + if err := l.Queries.TrackExecution(q, node.UUID, statuses[q]); err != nil { + log.Printf("error adding query execution %s", err) + } + // Check if query is completed + if err := l.Queries.VerifyComplete(q); err != nil { + log.Printf("error verifying and completing query %s", err) + } + } +} diff --git a/logging/utils.go b/logging/utils.go new file mode 100644 index 00000000..af115441 --- /dev/null +++ b/logging/utils.go @@ -0,0 +1,14 @@ +package logging + +// Helper to remove duplicates from array of strings +func uniq(duplicated []string) []string { + keys := make(map[string]bool) + result := []string{} + for _, entry := range duplicated { + if _, value := keys[entry]; !value { + keys[entry] = true + result = append(result, entry) + } + } + return result +} diff --git a/nodes/go.sum b/nodes/go.sum new file mode 100644 index 00000000..cded202f --- /dev/null +++ b/nodes/go.sum @@ -0,0 +1,123 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jinzhu/gorm v1.9.8 h1:n5uvxqLepIP2R1XF7pudpt9Rv8I3m7G9trGxJVjLZ5k= +github.com/jinzhu/gorm v1.9.8/go.mod h1:bdqTT3q6dhSph2K3pWxrHP6nqxuAp2yQ3KFtc3U3F84= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/nodes/metadata.go b/nodes/metadata.go new file mode 100644 index 00000000..480641c9 --- /dev/null +++ b/nodes/metadata.go @@ -0,0 +1,31 @@ +package nodes + +// NodeMetadata to hold metadata for a node +type NodeMetadata struct { + IPAddress string + Username string + OsqueryUser string + Hostname string + Localname string + ConfigHash string + DaemonHash string + OsqueryVersion string + Platform string + PlatformVersion string +} + +// GetMetadata to extract the metadata struct from a node +func (n *NodeManager) GetMetadata(node OsqueryNode) NodeMetadata { + return NodeMetadata{ + IPAddress: node.IPAddress, + Username: node.Username, + OsqueryUser: node.OsqueryUser, + Hostname: node.Hostname, + Localname: node.Localname, + ConfigHash: node.ConfigHash, + DaemonHash: node.DaemonHash, + OsqueryVersion: node.OsqueryVersion, + Platform: node.Platform, + PlatformVersion: node.PlatformVersion, + } +} diff --git a/nodes/nodes.go b/nodes/nodes.go index 50d9ec8f..b22bd6de 100644 --- a/nodes/nodes.go +++ b/nodes/nodes.go @@ -287,7 +287,7 @@ func (n *NodeManager) GetStatsByPlatform(platform string, hours int64) (StatsDat } // UpdateMetadataByUUID to update node metadata by UUID -func (n *NodeManager) UpdateMetadataByUUID(user, osqueryuser, hostname, localname, ipaddress, confighash, daemonhash, osqueryversion, uuid string) error { +func (n *NodeManager) UpdateMetadataByUUID(uuid string, metadata NodeMetadata) error { // Retrieve node node, err := n.GetByUUID(uuid) if err != nil { @@ -305,67 +305,67 @@ func (n *NodeManager) UpdateMetadataByUUID(user, osqueryuser, hostname, localnam OsqueryVersion: "", } // System user metadata update, if different - if (user != "") && (user != node.Username) { - data.Username = user + if (metadata.Username != "") && (metadata.Username != node.Username) { + data.Username = metadata.Username e := NodeHistoryUsername{ UUID: node.UUID, - Username: user, + Username: metadata.Username, } if err := n.NewHistoryUsername(e); err != nil { return fmt.Errorf("newNodeHistoryUsername %v", err) } } // Osquery user metadata update, if different - if (osqueryuser != "") && (osqueryuser != node.OsqueryUser) { - data.OsqueryUser = osqueryuser + if (metadata.OsqueryUser != "") && (metadata.OsqueryUser != node.OsqueryUser) { + data.OsqueryUser = metadata.OsqueryUser } // Hostname metadata update, if different - if (hostname != "") && (hostname != node.Hostname) { - data.Hostname = hostname + if (metadata.Hostname != "") && (metadata.Hostname != node.Hostname) { + data.Hostname = metadata.Hostname e := NodeHistoryHostname{ UUID: node.UUID, - Hostname: hostname, + Hostname: metadata.Hostname, } if err := n.NewHistoryHostname(e); err != nil { return fmt.Errorf("newNodeHistoryHostname %v", err) } } // Localname metadata update, if different - if (localname != "") && (localname != node.Localname) { - data.Localname = localname + if (metadata.Localname != "") && (metadata.Localname != node.Localname) { + data.Localname = metadata.Localname e := NodeHistoryLocalname{ UUID: node.UUID, - Localname: localname, + Localname: metadata.Localname, } if err := n.NewHistoryLocalname(e); err != nil { return fmt.Errorf("newNodeHistoryLocalname %v", err) } } // IP Address metadata update, if different - if (ipaddress != "") && (ipaddress != node.IPAddress) { - data.IPAddress = ipaddress + if (metadata.IPAddress != "") && (metadata.IPAddress != node.IPAddress) { + data.IPAddress = metadata.IPAddress e := NodeHistoryIPAddress{ UUID: node.UUID, - IPAddress: ipaddress, + IPAddress: metadata.IPAddress, Count: 1, } if err := n.NewHistoryIPAddress(e); err != nil { return fmt.Errorf("newNodeHistoryIPAddress %v", err) } - } else if err := n.IncHistoryIPAddress(node.UUID, ipaddress); err != nil { + } else if err := n.IncHistoryIPAddress(node.UUID, metadata.IPAddress); err != nil { return fmt.Errorf("incNodeHistoryIPAddress %v", err) } // Osquery configuration metadata update, if different - if (confighash != "") && (confighash != node.ConfigHash) { - data.ConfigHash = confighash + if (metadata.ConfigHash != "") && (metadata.ConfigHash != node.ConfigHash) { + data.ConfigHash = metadata.ConfigHash } // Osquery daemon hash update, if different - if (daemonhash != "") && (daemonhash != node.DaemonHash) { - data.DaemonHash = daemonhash + if (metadata.DaemonHash != "") && (metadata.DaemonHash != node.DaemonHash) { + data.DaemonHash = metadata.DaemonHash } // Osquery version metadata update, if different - if (osqueryversion != "") && (osqueryversion != node.OsqueryVersion) { - data.OsqueryVersion = osqueryversion + if (metadata.OsqueryVersion != "") && (metadata.OsqueryVersion != node.OsqueryVersion) { + data.OsqueryVersion = metadata.OsqueryVersion } if err := n.DB.Model(&node).Updates(data).Error; err != nil { return fmt.Errorf("Updates %v", err) diff --git a/tls/carving.go b/tls/handlers/carves.go similarity index 58% rename from tls/carving.go rename to tls/handlers/carves.go index 117b1e14..da953141 100644 --- a/tls/carving.go +++ b/tls/handlers/carves.go @@ -1,4 +1,4 @@ -package main +package handlers import ( "log" @@ -7,12 +7,12 @@ import ( "github.com/jmpsec/osctrl/types" ) -// Function to initialize a file carve from a node -func processCarveInit(req types.CarveInitRequest, sessionid, environment string) error { +// ProcessCarveInit - Function to initialize a file carve from a node +func (h *HandlersTLS) ProcessCarveInit(req types.CarveInitRequest, sessionid, environment string) error { // Retrieve node - node, err := nodesmgr.GetByKey(req.NodeKey) + node, err := h.Nodes.GetByKey(req.NodeKey) if err != nil { - incMetric(metricInitErr) + h.Inc(metricInitErr) log.Printf("error retrieving node %s", err) return err } @@ -30,18 +30,18 @@ func processCarveInit(req types.CarveInitRequest, sessionid, environment string) Status: carves.StatusInitialized, } // Create File Carve - err = filecarves.CreateCarve(carve) + err = h.Carves.CreateCarve(carve) if err != nil { - incMetric(metricInitErr) + h.Inc(metricInitErr) log.Printf("error creating CarvedFile %v", err) return err } return nil } -// Function to process one block from a file carve +// ProcessCarveBlock - Function to process one block from a file carve // FIXME it can be more efficient on db access -func processCarveBlock(req types.CarveBlockRequest, environment string) { +func (h *HandlersTLS) ProcessCarveBlock(req types.CarveBlockRequest, environment string) { // Prepare carve block block := carves.CarvedBlock{ RequestID: req.RequestID, @@ -52,24 +52,24 @@ func processCarveBlock(req types.CarveBlockRequest, environment string) { Size: len(req.Data), } // Create Block - if err := filecarves.CreateBlock(block); err != nil { - incMetric(metricBlockErr) + if err := h.Carves.CreateBlock(block); err != nil { + h.Inc(metricBlockErr) log.Printf("error creating CarvedBlock %v", err) } // Bump block completion - if err := filecarves.CompleteBlock(req.SessionID); err != nil { - incMetric(metricBlockErr) + if err := h.Carves.CompleteBlock(req.SessionID); err != nil { + h.Inc(metricBlockErr) log.Printf("error completing block %v", err) } // If it is completed, set status - if filecarves.Completed(req.SessionID) { - if err := filecarves.ChangeStatus(carves.StatusCompleted, req.SessionID); err != nil { - incMetric(metricBlockErr) + if h.Carves.Completed(req.SessionID) { + if err := h.Carves.ChangeStatus(carves.StatusCompleted, req.SessionID); err != nil { + h.Inc(metricBlockErr) log.Printf("error completing carve %v", err) } } else { - if err := filecarves.ChangeStatus(carves.StatusInProgress, req.SessionID); err != nil { - incMetric(metricBlockErr) + if err := h.Carves.ChangeStatus(carves.StatusInProgress, req.SessionID); err != nil { + h.Inc(metricBlockErr) log.Printf("error progressing carve %v", err) } } diff --git a/tls/handlers/go.mod b/tls/handlers/go.mod new file mode 100644 index 00000000..884293de --- /dev/null +++ b/tls/handlers/go.mod @@ -0,0 +1,5 @@ +module github.com/javuto/osctrl/tls/handlers + +go 1.12 + +require github.com/stretchr/testify v1.5.1 diff --git a/tls/handlers/go.sum b/tls/handlers/go.sum new file mode 100644 index 00000000..fb52f53a --- /dev/null +++ b/tls/handlers/go.sum @@ -0,0 +1,6 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/tls/handlers-tls.go b/tls/handlers/handlers.go similarity index 58% rename from tls/handlers-tls.go rename to tls/handlers/handlers.go index d09cf7fe..c3381642 100644 --- a/tls/handlers-tls.go +++ b/tls/handlers/handlers.go @@ -1,4 +1,4 @@ -package main +package handlers import ( "compress/gzip" @@ -8,7 +8,10 @@ import ( "strings" "github.com/gorilla/mux" + "github.com/jmpsec/osctrl/carves" "github.com/jmpsec/osctrl/environments" + "github.com/jmpsec/osctrl/logging" + "github.com/jmpsec/osctrl/metrics" "github.com/jmpsec/osctrl/nodes" "github.com/jmpsec/osctrl/queries" "github.com/jmpsec/osctrl/settings" @@ -45,50 +48,135 @@ const ( metricOnelinerOk = "oneliner-ok" ) -// Handler to be used as health check -func okHTTPHandler(w http.ResponseWriter, r *http.Request) { +// HandlersTLS to keep all handlers for TLS +type HandlersTLS struct { + Envs *environments.Environment + EnvsMap environments.MapEnvironments + Nodes *nodes.NodeManager + Queries *queries.Queries + Carves *carves.Carves + Settings *settings.Settings + SettingsMap settings.MapSettings + Metrics *metrics.Metrics + Logs *logging.LoggerTLS +} + +type HandlersOption func(*HandlersTLS) + +func WithEnvs(envs *environments.Environment) HandlersOption { + return func(h *HandlersTLS) { + h.Envs = envs + } +} + +func WithEnvsMap(envsmap environments.MapEnvironments) HandlersOption { + return func(h *HandlersTLS) { + h.EnvsMap = envsmap + } +} + +func WithNodes(nodes *nodes.NodeManager) HandlersOption { + return func(h *HandlersTLS) { + h.Nodes = nodes + } +} + +func WithQueries(queries *queries.Queries) HandlersOption { + return func(h *HandlersTLS) { + h.Queries = queries + } +} + +func WithCarves(carves *carves.Carves) HandlersOption { + return func(h *HandlersTLS) { + h.Carves = carves + } +} + +func WithSettings(settings *settings.Settings) HandlersOption { + return func(h *HandlersTLS) { + h.Settings = settings + } +} + +func WithSettingsMap(settingsmap settings.MapSettings) HandlersOption { + return func(h *HandlersTLS) { + h.SettingsMap = settingsmap + } +} + +func WithMetrics(metrics *metrics.Metrics) HandlersOption { + return func(h *HandlersTLS) { + h.Metrics = metrics + } +} + +func WithLogs(logs *logging.LoggerTLS) HandlersOption { + return func(h *HandlersTLS) { + h.Logs = logs + } +} + +// CreateHandlersTLS to initialize the TLS handlers struct +func CreateHandlersTLS(opts ...HandlersOption) *HandlersTLS { + h := &HandlersTLS{} + for _, opt := range opts { + opt(h) + } + return h +} + +// Helper to send metrics if it is enabled +func (h *HandlersTLS) Inc(name string) { + if h.Metrics != nil && h.Settings.ServiceMetrics(settings.ServiceTLS) { + h.Metrics.Inc(name) + } +} + +// RootHandler to be used as health check +func (h *HandlersTLS) RootHandler(w http.ResponseWriter, r *http.Request) { // Send response utils.HTTPResponse(w, "", http.StatusOK, []byte("💥")) } -// Handle health requests -func healthHTTPHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricHealthReq) +// HealthHandler for health requests +func (h *HandlersTLS) HealthHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricHealthReq) // Send response utils.HTTPResponse(w, "", http.StatusOK, []byte("✅")) - incMetric(metricHealthOK) + h.Inc(metricHealthOK) } -// Handle error requests -func errorHTTPHandler(w http.ResponseWriter, r *http.Request) { +// ErrorHandler for error requests +func (h *HandlersTLS) ErrorHandler(w http.ResponseWriter, r *http.Request) { // Send response utils.HTTPResponse(w, "", http.StatusInternalServerError, []byte("uh oh...")) } -// Function to handle the enroll requests from osquery nodes -func enrollHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricEnrollReq) +// EnrollHandler - Function to handle the enroll requests from osquery nodes +func (h *HandlersTLS) EnrollHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricEnrollReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricEnrollErr) + h.Inc(metricEnrollErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricEnrollErr) + if !h.Envs.Exists(env) { + h.Inc(metricEnrollErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP for environment - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Decode read POST body var t types.EnrollRequest err := json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricEnrollErr) + h.Inc(metricEnrollErr) log.Printf("error parsing POST body %v", err) return } @@ -96,72 +184,72 @@ func enrollHandler(w http.ResponseWriter, r *http.Request) { var nodeKey string var newNode nodes.OsqueryNode nodeInvalid := true - if checkValidSecret(t.EnrollSecret, env) { + if h.checkValidSecret(t.EnrollSecret, env) { // Generate node_key using UUID as entropy nodeKey = generateNodeKey(t.HostIdentifier) newNode = nodeFromEnroll(t, env, r.Header.Get("X-Real-IP"), nodeKey) // Check if UUID exists already, if so archive node and enroll new node - if nodesmgr.CheckByUUID(t.HostIdentifier) { - err := nodesmgr.Archive(t.HostIdentifier, "exists") + if h.Nodes.CheckByUUID(t.HostIdentifier) { + err := h.Nodes.Archive(t.HostIdentifier, "exists") if err != nil { - incMetric(metricEnrollErr) + h.Inc(metricEnrollErr) log.Printf("error archiving node %v", err) } // Update existing with new enroll data - err = nodesmgr.UpdateByUUID(newNode, t.HostIdentifier) + err = h.Nodes.UpdateByUUID(newNode, t.HostIdentifier) if err != nil { - incMetric(metricEnrollErr) + h.Inc(metricEnrollErr) log.Printf("error updating existing node %v", err) } else { nodeInvalid = false } } else { // New node, persist it - err := nodesmgr.Create(newNode) + err := h.Nodes.Create(newNode) if err != nil { - incMetric(metricEnrollErr) + h.Inc(metricEnrollErr) log.Printf("error creating node %v", err) } else { nodeInvalid = false } } } else { - incMetric(metricEnrollErr) + h.Inc(metricEnrollErr) log.Printf("error invalid enrolling secret %s", t.EnrollSecret) } response := types.EnrollResponse{NodeKey: nodeKey, NodeInvalid: nodeInvalid} // Debug HTTP - if envsmap[env].DebugHTTP { + if h.EnvsMap[env].DebugHTTP { log.Printf("Response: %+v", response) } // Serialize and send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricEnrollOK) + h.Inc(metricEnrollOK) } -// Function to handle the configuration requests from osquery nodes -func configHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricConfigReq) +// ConfigHandler - Function to handle the configuration requests from osquery nodes +func (h *HandlersTLS) ConfigHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricConfigReq) var response interface{} // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricConfigErr) + h.Inc(metricConfigErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricConfigErr) + if !h.Envs.Exists(env) { + h.Inc(metricConfigErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP for environment - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Get environment - e, err := envs.Get(env) + e, err := h.Envs.Get(env) if err != nil { - incMetric(metricConfigErr) + h.Inc(metricConfigErr) log.Printf("error getting environment %v", err) return } @@ -169,21 +257,21 @@ func configHandler(w http.ResponseWriter, r *http.Request) { var t types.ConfigRequest err = json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricConfigErr) + h.Inc(metricConfigErr) log.Printf("error parsing POST body %v", err) return } // Check if provided node_key is valid and if so, update node - if nodesmgr.CheckByKey(t.NodeKey) { - err = nodesmgr.UpdateIPAddressByKey(r.Header.Get("X-Real-IP"), t.NodeKey) + if h.Nodes.CheckByKey(t.NodeKey) { + err = h.Nodes.UpdateIPAddressByKey(r.Header.Get("X-Real-IP"), t.NodeKey) if err != nil { - incMetric(metricConfigErr) + h.Inc(metricConfigErr) log.Printf("error updating IP address %v", err) } // Refresh last config for node - err = nodesmgr.RefreshLastConfig(t.NodeKey) + err = h.Nodes.RefreshLastConfig(t.NodeKey) if err != nil { - incMetric(metricConfigErr) + h.Inc(metricConfigErr) log.Printf("error refreshing last config %v", err) } response = []byte(e.Configuration) @@ -191,7 +279,7 @@ func configHandler(w http.ResponseWriter, r *http.Request) { response = types.ConfigResponse{NodeInvalid: true} } // Debug HTTP - if envsmap[env].DebugHTTP { + if h.EnvsMap[env].DebugHTTP { if x, ok := response.([]byte); ok { log.Printf("Configuration: %s", string(x)) } else { @@ -200,23 +288,23 @@ func configHandler(w http.ResponseWriter, r *http.Request) { } // Send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricConfigOK) + h.Inc(metricConfigOK) } -// Function to handle the log requests from osquery nodes, both status and results -func logHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricLogReq) +// LogHandler - Function to handle the log requests from osquery nodes, both status and results +func (h *HandlersTLS) LogHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricLogReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricLogErr) + h.Inc(metricLogErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricLogErr) + if !h.Envs.Exists(env) { + h.Inc(metricLogErr) log.Printf("error unknown environment (%s)", env) return } @@ -225,25 +313,25 @@ func logHandler(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Content-Encoding") == "gzip" { r.Body, err = gzip.NewReader(r.Body) if err != nil { - incMetric(metricLogErr) + h.Inc(metricLogErr) log.Printf("error decoding gzip body %v", err) } //defer r.Body.Close() defer func() { err := r.Body.Close() if err != nil { - incMetric(metricLogErr) + h.Inc(metricLogErr) log.Printf("Failed to close body %v", err) } }() } // Debug HTTP here so the body will be uncompressed - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Extract POST body and decode JSON var t types.LogRequest err = json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricLogErr) + h.Inc(metricLogErr) log.Printf("error parsing POST body %v", err) return } @@ -251,77 +339,77 @@ func logHandler(w http.ResponseWriter, r *http.Request) { defer func() { err := r.Body.Close() if err != nil { - incMetric(metricLogErr) + h.Inc(metricLogErr) log.Printf("Failed to close body %v", err) } }() var nodeInvalid bool // Check if provided node_key is valid and if so, update node - if nodesmgr.CheckByKey(t.NodeKey) { + if h.Nodes.CheckByKey(t.NodeKey) { nodeInvalid = false // Process logs and update metadata - processLogs(t.Data, t.LogType, env, r.Header.Get("X-Real-IP")) + h.Logs.ProcessLogs(t.Data, t.LogType, env, r.Header.Get("X-Real-IP"), h.EnvsMap[env].DebugHTTP) } else { nodeInvalid = true } // Prepare response response := types.LogResponse{NodeInvalid: nodeInvalid} // Debug - if envsmap[env].DebugHTTP { + if h.EnvsMap[env].DebugHTTP { log.Printf("Response: %+v", response) } // Serialize and send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricLogOK) + h.Inc(metricLogOK) } -// Function to handle on-demand queries to osquery nodes -func queryReadHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricReadReq) +// QueryReadHandler - Function to handle on-demand queries to osquery nodes +func (h *HandlersTLS) QueryReadHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricReadReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricReadErr) + h.Inc(metricReadErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricReadErr) + if !h.Envs.Exists(env) { + h.Inc(metricReadErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Decode read POST body var t types.QueryReadRequest err := json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricReadErr) + h.Inc(metricReadErr) log.Printf("error parsing POST body %v", err) return } var nodeInvalid, accelerate bool qs := make(queries.QueryReadQueries) // Lookup node by node_key - node, err := nodesmgr.GetByKey(t.NodeKey) + node, err := h.Nodes.GetByKey(t.NodeKey) if err == nil { - err = nodesmgr.UpdateIPAddress(r.Header.Get("X-Real-IP"), node) + err = h.Nodes.UpdateIPAddress(r.Header.Get("X-Real-IP"), node) if err != nil { - incMetric(metricReadErr) + h.Inc(metricReadErr) log.Printf("error updating IP Address %v", err) } nodeInvalid = false - qs, accelerate, err = queriesmgr.NodeQueries(node) + qs, accelerate, err = h.Queries.NodeQueries(node) if err != nil { - incMetric(metricReadErr) + h.Inc(metricReadErr) log.Printf("error getting queries from db %v", err) } // Refresh last query read request - err = nodesmgr.RefreshLastQueryRead(t.NodeKey) + err = h.Nodes.RefreshLastQueryRead(t.NodeKey) if err != nil { - incMetric(metricReadErr) + h.Inc(metricReadErr) log.Printf("error refreshing last query read %v", err) } } else { @@ -331,235 +419,235 @@ func queryReadHandler(w http.ResponseWriter, r *http.Request) { // Prepare response and serialize queries var response interface{} if accelerate { - sAccelerate := int(settingsmap[settings.AcceleratedSeconds].Integer) + sAccelerate := int(h.SettingsMap[settings.AcceleratedSeconds].Integer) response = types.AcceleratedQueryReadResponse{Queries: qs, Accelerate: sAccelerate, NodeInvalid: nodeInvalid} } else { response = types.QueryReadResponse{Queries: qs, NodeInvalid: nodeInvalid} } // Debug HTTP - if envsmap[env].DebugHTTP { + if h.EnvsMap[env].DebugHTTP { log.Printf("Response: %+v", response) } // Serialize and send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricReadOK) + h.Inc(metricReadOK) } // Function to handle distributed query results from osquery nodes -func queryWriteHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricWriteReq) +func (h *HandlersTLS) QueryWriteHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricWriteReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricWriteErr) + h.Inc(metricWriteErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricWriteErr) + if !h.Envs.Exists(env) { + h.Inc(metricWriteErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Decode read POST body var t types.QueryWriteRequest err := json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricWriteErr) + h.Inc(metricWriteErr) log.Printf("error parsing POST body %v", err) return } var nodeInvalid bool // Check if provided node_key is valid and if so, update node - if nodesmgr.CheckByKey(t.NodeKey) { - err = nodesmgr.UpdateIPAddressByKey(r.Header.Get("X-Real-IP"), t.NodeKey) + if h.Nodes.CheckByKey(t.NodeKey) { + err = h.Nodes.UpdateIPAddressByKey(r.Header.Get("X-Real-IP"), t.NodeKey) if err != nil { - incMetric(metricWriteErr) + h.Inc(metricWriteErr) log.Printf("error updating IP Address %v", err) } nodeInvalid = false // Process submitted results - go processLogQueryResult(t.Queries, t.Statuses, t.NodeKey, env) + go h.Logs.ProcessLogQueryResult(t.Queries, t.Statuses, t.NodeKey, env, h.EnvsMap[env].DebugHTTP) } else { nodeInvalid = true } // Prepare response - response:= types.QueryWriteResponse{NodeInvalid: nodeInvalid} + response := types.QueryWriteResponse{NodeInvalid: nodeInvalid} // Debug HTTP - if envsmap[env].DebugHTTP { + if h.EnvsMap[env].DebugHTTP { log.Printf("Response: %+v", response) } // Send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricWriteOK) + h.Inc(metricWriteOK) } -// Function to handle the endpoint for quick enrollment script distribution -func quickEnrollHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricOnelinerReq) +// QuickEnrollHandler - Function to handle the endpoint for quick enrollment script distribution +func (h *HandlersTLS) QuickEnrollHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricOnelinerReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricOnelinerErr) + h.Inc(metricOnelinerErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricOnelinerErr) + if !h.Envs.Exists(env) { + h.Inc(metricOnelinerErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) - e, err := envs.Get(env) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + e, err := h.Envs.Get(env) if err != nil { - incMetric(metricOnelinerErr) + h.Inc(metricOnelinerErr) log.Printf("error getting environment %v", err) return } // Retrieve type of script script, ok := vars["script"] if !ok { - incMetric(metricOnelinerErr) + h.Inc(metricOnelinerErr) log.Println("Script is missing") return } // Retrieve SecretPath variable secretPath, ok := vars["secretpath"] if !ok { - incMetric(metricOnelinerErr) + h.Inc(metricOnelinerErr) log.Println("Path is missing") return } // Check if provided SecretPath is valid and is not expired if strings.HasPrefix(script, "enroll") { - if !checkValidEnrollSecretPath(env, secretPath) { - incMetric(metricOnelinerErr) + if !h.checkValidEnrollSecretPath(env, secretPath) { + h.Inc(metricOnelinerErr) log.Println("Invalid Path") return } } else if strings.HasPrefix(script, "remove") { - if !checkValidRemoveSecretPath(env, secretPath) { - incMetric(metricOnelinerErr) + if !h.checkValidRemoveSecretPath(env, secretPath) { + h.Inc(metricOnelinerErr) log.Println("Invalid Path") return } } // Prepare response with the script - quickScript, err := environments.QuickAddScript(projectName, script, e) + quickScript, err := environments.QuickAddScript("", script, e) if err != nil { - incMetric(metricOnelinerErr) + h.Inc(metricOnelinerErr) log.Printf("error getting script %v", err) return } // Send response utils.HTTPResponse(w, utils.TextPlainUTF8, http.StatusOK, []byte(quickScript)) - incMetric(metricOnelinerOk) + h.Inc(metricOnelinerOk) } -// Function to handle the initialization of the file carver +// CarveInitHandler - Function to handle the initialization of the file carver // This function does not use go routines to handle requests because the session_id returned // must be already created in the DB, otherwise block requests will fail. -func carveInitHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricInitReq) +func (h *HandlersTLS) CarveInitHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricInitReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricInitErr) + h.Inc(metricInitErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricInitErr) + if !h.Envs.Exists(env) { + h.Inc(metricInitErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Decode read POST body var t types.CarveInitRequest err := json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricInitErr) + h.Inc(metricInitErr) log.Printf("error parsing POST body %v", err) return } initCarve := false var carveSessionID string // Check if provided node_key is valid and if so, update node - if nodesmgr.CheckByKey(t.NodeKey) { - err = nodesmgr.UpdateIPAddressByKey(r.Header.Get("X-Real-IP"), t.NodeKey) + if h.Nodes.CheckByKey(t.NodeKey) { + err = h.Nodes.UpdateIPAddressByKey(r.Header.Get("X-Real-IP"), t.NodeKey) if err != nil { - incMetric(metricInitErr) + h.Inc(metricInitErr) log.Printf("error updating IP Address %v", err) } initCarve = true carveSessionID = generateCarveSessionID() // Process carve init - if err := processCarveInit(t, carveSessionID, env); err != nil { - incMetric(metricInitErr) + if err := h.ProcessCarveInit(t, carveSessionID, env); err != nil { + h.Inc(metricInitErr) log.Printf("error procesing carve init %v", err) initCarve = false } } // Prepare response - response:=types.CarveInitResponse{Success: initCarve, SessionID: carveSessionID} + response := types.CarveInitResponse{Success: initCarve, SessionID: carveSessionID} // Debug HTTP - if envsmap[env].DebugHTTP { + if h.EnvsMap[env].DebugHTTP { log.Printf("Response: %+v", response) } // Send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricInitOK) + h.Inc(metricInitOK) } -// Function to handle the blocks of the file carver -func carveBlockHandler(w http.ResponseWriter, r *http.Request) { - incMetric(metricBlockReq) +// CarveBlockHandler - Function to handle the blocks of the file carver +func (h *HandlersTLS) CarveBlockHandler(w http.ResponseWriter, r *http.Request) { + h.Inc(metricBlockReq) // Retrieve environment variable vars := mux.Vars(r) env, ok := vars["environment"] if !ok { - incMetric(metricBlockErr) + h.Inc(metricBlockErr) log.Println("Environment is missing") return } // Check if environment is valid - if !envs.Exists(env) { - incMetric(metricBlockErr) + if !h.Envs.Exists(env) { + h.Inc(metricBlockErr) log.Printf("error unknown environment (%s)", env) return } // Debug HTTP - utils.DebugHTTPDump(r, envsmap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) // Decode read POST body var t types.CarveBlockRequest err := json.NewDecoder(r.Body).Decode(&t) if err != nil { - incMetric(metricBlockErr) + h.Inc(metricBlockErr) log.Printf("error parsing POST body %v", err) return } blockCarve := false // Check if provided session_id matches with the request_id (carve query name) - if filecarves.CheckCarve(t.SessionID, t.RequestID) { + if h.Carves.CheckCarve(t.SessionID, t.RequestID) { blockCarve = true // Process received block - go processCarveBlock(t, env) + go h.ProcessCarveBlock(t, env) } // Prepare response - response:=types.CarveBlockResponse{Success: blockCarve} - if envsmap[env].DebugHTTP { + response := types.CarveBlockResponse{Success: blockCarve} + if h.EnvsMap[env].DebugHTTP { log.Printf("Response: %+v", response) } // Send response utils.HTTPResponse(w, utils.JSONApplicationUTF8, http.StatusOK, response) - incMetric(metricBlockOK) + h.Inc(metricBlockOK) } diff --git a/tls/handlers/utils.go b/tls/handlers/utils.go new file mode 100644 index 00000000..9ba6c0b4 --- /dev/null +++ b/tls/handlers/utils.go @@ -0,0 +1,107 @@ +package handlers + +import ( + "bytes" + "crypto/md5" + "encoding/hex" + "encoding/json" + "log" + "strconv" + "strings" + "time" + + "github.com/jmpsec/osctrl/environments" + "github.com/jmpsec/osctrl/nodes" + "github.com/jmpsec/osctrl/types" + "github.com/segmentio/ksuid" +) + +// Helper to generate a random enough node key +func generateNodeKey(uuid string) string { + timestamp := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) + hasher := md5.New() + _, _ = hasher.Write([]byte(uuid + timestamp)) + return hex.EncodeToString(hasher.Sum(nil)) +} + +// Helper to generate a carve session_id using KSUID +// See https://github.com/segmentio/ksuid for more info about KSUIDs +func generateCarveSessionID() string { + id := ksuid.New() + return id.String() +} + +// Helper to check if the provided secret is valid for this environment +func (h *HandlersTLS) checkValidSecret(enrollSecret string, environment string) bool { + env, err := h.Envs.Get(environment) + if err != nil { + return false + } + return (strings.TrimSpace(enrollSecret) == env.Secret) +} + +// Helper to check if the provided SecretPath is valid for enrolling in a environment +func (h *HandlersTLS) checkValidEnrollSecretPath(environment, secretpath string) bool { + env, err := h.Envs.Get(environment) + if err != nil { + return false + } + return ((strings.TrimSpace(secretpath) == env.EnrollSecretPath) && (!environments.IsItExpired(env.EnrollExpire))) +} + +// Helper to check if the provided SecretPath is valid for removing in a environment +func (h *HandlersTLS) checkValidRemoveSecretPath(environment, secretpath string) bool { + env, err := h.Envs.Get(environment) + if err != nil { + return false + } + return ((strings.TrimSpace(secretpath) == env.RemoveSecretPath) && (!environments.IsItExpired(env.RemoveExpire))) +} + +// Helper to convert an enrollment request into a osquery node +func nodeFromEnroll(req types.EnrollRequest, environment, ipaddress, nodekey string) nodes.OsqueryNode { + // Prepare the enrollment request to be stored as raw JSON + enrollRaw, err := json.Marshal(req) + if err != nil { + log.Printf("error serializing enrollment: %v", err) + enrollRaw = []byte("") + } + // Avoid the error "unsupported Unicode escape sequence" due to \u0000 + enrollRaw = bytes.Replace(enrollRaw, []byte("\\u0000"), []byte(""), -1) + return nodes.OsqueryNode{ + NodeKey: nodekey, + UUID: strings.ToUpper(req.HostIdentifier), + Platform: req.HostDetails.EnrollOSVersion.Platform, + PlatformVersion: req.HostDetails.EnrollOSVersion.Version, + OsqueryVersion: req.HostDetails.EnrollOsqueryInfo.Version, + Hostname: req.HostDetails.EnrollSystemInfo.Hostname, + Localname: req.HostDetails.EnrollSystemInfo.LocalHostname, + IPAddress: ipaddress, + Username: "unknown", + OsqueryUser: "unknown", + Environment: environment, + CPU: strings.TrimRight(req.HostDetails.EnrollSystemInfo.CPUBrand, "\x00"), + Memory: req.HostDetails.EnrollSystemInfo.PhysicalMemory, + HardwareSerial: req.HostDetails.EnrollSystemInfo.HardwareSerial, + ConfigHash: req.HostDetails.EnrollOsqueryInfo.ConfigHash, + RawEnrollment: enrollRaw, + LastStatus: time.Time{}, + LastResult: time.Time{}, + LastConfig: time.Time{}, + LastQueryRead: time.Time{}, + LastQueryWrite: time.Time{}, + } +} + +// Helper to remove duplicates from array of strings +func uniq(duplicated []string) []string { + keys := make(map[string]bool) + result := []string{} + for _, entry := range duplicated { + if _, value := keys[entry]; !value { + keys[entry] = true + result = append(result, entry) + } + } + return result +} diff --git a/tls/logs.go b/tls/logs.go deleted file mode 100644 index 43b9bd70..00000000 --- a/tls/logs.go +++ /dev/null @@ -1,137 +0,0 @@ -package main - -import ( - "encoding/json" - "log" - - "github.com/jmpsec/osctrl/nodes" - "github.com/jmpsec/osctrl/types" -) - -// Helper to process logs -func processLogs(data json.RawMessage, logType, environment, ipaddress string) { - // Parse log to extract metadata - var logs []types.LogGenericData - err := json.Unmarshal(data, &logs) - if err != nil { - // FIXME metrics for this - log.Printf("error parsing log %s %v", string(data), err) - } - // Iterate through received messages to extract metadata - var uuids, hosts, names, users, osqueryusers, hashes, dhashes, osqueryversions []string - for _, l := range logs { - uuids = append(uuids, l.HostIdentifier) - hosts = append(hosts, l.Decorations.Hostname) - names = append(names, l.Decorations.LocalHostname) - users = append(users, l.Decorations.Username) - osqueryusers = append(osqueryusers, l.Decorations.OsqueryUser) - hashes = append(hashes, l.Decorations.ConfigHash) - dhashes = append(dhashes, l.Decorations.DaemonHash) - osqueryversions = append(osqueryversions, l.Version) - } - // FIXME it only uses the first element from the []string that uniq returns - uuid := uniq(uuids)[0] - user := uniq(users)[0] - osqueryuser := uniq(osqueryusers)[0] - host := uniq(hosts)[0] - name := uniq(names)[0] - hash := uniq(hashes)[0] - dhash := uniq(dhashes)[0] - osqueryversion := uniq(osqueryversions)[0] - // Dispatch logs and update metadata - dispatchLogs(data, uuid, ipaddress, user, osqueryuser, host, name, hash, dhash, osqueryversion, logType, environment) -} - -// Helper to dispatch logs -func dispatchLogs(data []byte, uuid, ipaddress, user, osqueryuser, hostname, localname, hash, dhash, osqueryversion, logType, environment string) { - // Use metadata to update record - if err := nodesmgr.UpdateMetadataByUUID(user, osqueryuser, hostname, localname, ipaddress, hash, dhash, osqueryversion, uuid); err != nil { - log.Printf("error updating metadata %s", err) - } - // Send data to storage - // FIXME allow multiple types of logging - if envsmap[environment].DebugHTTP { - log.Printf("dispatching logs to %s", tlsConfig.Logging) - } - loggerTLS.Log( - logType, - data, - environment, - uuid, - envsmap[environment].DebugHTTP) - // Refresh last logging request - if logType == types.StatusLog { - err := nodesmgr.RefreshLastStatus(uuid) - if err != nil { - log.Printf("error refreshing last status %v", err) - } - } - if logType == types.ResultLog { - if err := nodesmgr.RefreshLastResult(uuid); err != nil { - log.Printf("error refreshing last result %v", err) - } - } -} - -// Helper to dispatch queries -func dispatchQueries(queryData types.QueryWriteData, node nodes.OsqueryNode) { - // Prepare data to send - data, err := json.Marshal(queryData) - if err != nil { - log.Printf("error preparing data %v", err) - } - // Refresh last query write request - if err := nodesmgr.RefreshLastQueryWrite(node.UUID); err != nil { - log.Printf("error refreshing last query write %v", err) - } - // Send data to storage - // FIXME allow multiple types of logging - if envsmap[node.Environment].DebugHTTP { - log.Printf("dispatching queries to %s", tlsConfig.Logging) - } - loggerTLS.QueryLog( - types.QueryLog, - data, - node.Environment, - node.UUID, - queryData.Name, - queryData.Status, - envsmap[node.Environment].DebugHTTP) -} - -// Helper to process on-demand query result logs -func processLogQueryResult(queries types.QueryWriteQueries, statuses types.QueryWriteStatuses, nodeKey string, environment string) { - // Retrieve node - node, err := nodesmgr.GetByKey(nodeKey) - if err != nil { - log.Printf("error retrieving node %s", err) - } - // Tap into results so we can update internal metrics - for q, r := range queries { - // Dispatch query name, result and status - d := types.QueryWriteData{ - Name: q, - Result: r, - Status: statuses[q], - } - go dispatchQueries(d, node) - // Update internal metrics per query - var err error - if statuses[q] != 0 { - err = queriesmgr.IncError(q) - } else { - err = queriesmgr.IncExecution(q) - } - if err != nil { - log.Printf("error updating query %s", err) - } - // Add a record for this query - if err := queriesmgr.TrackExecution(q, node.UUID, statuses[q]); err != nil { - log.Printf("error adding query execution %s", err) - } - // Check if query is completed - if err := queriesmgr.VerifyComplete(q); err != nil { - log.Printf("error verifying and completing query %s", err) - } - } -} diff --git a/tls/main.go b/tls/main.go index e12ea438..8d15e85c 100644 --- a/tls/main.go +++ b/tls/main.go @@ -15,6 +15,7 @@ import ( "github.com/jmpsec/osctrl/nodes" "github.com/jmpsec/osctrl/queries" "github.com/jmpsec/osctrl/settings" + "github.com/jmpsec/osctrl/tls/handlers" "github.com/jmpsec/osctrl/types" "github.com/gorilla/mux" @@ -45,6 +46,8 @@ const ( defaultRefresh int = 300 // Default accelerate interval in seconds defaultAccelerate int = 300 + // Default value for keeping maps updated in handlers + defaultMapRefresh int = 60 ) var ( @@ -54,19 +57,18 @@ var ( // Global variables var ( - tlsConfig types.JSONConfigurationService - db *gorm.DB - settingsmgr *settings.Settings - envs *environments.Environment - envsmap environments.MapEnvironments - envsTicker *time.Ticker - settingsmap settings.MapSettings - settingsTicker *time.Ticker - nodesmgr *nodes.NodeManager - queriesmgr *queries.Queries - filecarves *carves.Carves - _metrics *metrics.Metrics - loggerTLS *logging.LoggerTLS + tlsConfig types.JSONConfigurationService + db *gorm.DB + settingsmgr *settings.Settings + envs *environments.Environment + envsmap environments.MapEnvironments + settingsmap settings.MapSettings + nodesmgr *nodes.NodeManager + queriesmgr *queries.Queries + filecarves *carves.Carves + _metrics *metrics.Metrics + loggerTLS *logging.LoggerTLS + handlersTLS *handlers.HandlersTLS ) // Variables for flags @@ -178,43 +180,16 @@ func main() { loadingSettings() // Initialize TLS logger log.Println("Loading TLS logger") - loggerTLS, err = logging.CreateLoggerTLS(tlsConfig.Logging, settingsmgr) + loggerTLS, err = logging.CreateLoggerTLS(tlsConfig.Logging, settingsmgr, nodesmgr, queriesmgr) if err != nil { log.Printf("Error loading logger - %s: %v", tlsConfig.Logging, err) } - // multiple listeners channel - finish := make(chan bool) - - /////////////////////////// ALL CONTENT IS UNAUTHENTICATED FOR TLS - if settingsmgr.DebugService(settings.ServiceTLS) { - log.Println("DebugService: Creating router") - } - // Create router for TLS endpoint - routerTLS := mux.NewRouter() - // TLS: root - routerTLS.HandleFunc("/", okHTTPHandler) - // TLS: testing - routerTLS.HandleFunc(healthPath, healthHTTPHandler).Methods("GET") - // TLS: error - routerTLS.HandleFunc(errorPath, errorHTTPHandler).Methods("GET") - // TLS: Specific routes for osquery nodes - // FIXME this forces all paths to be the same - routerTLS.HandleFunc("/{environment}/"+environments.DefaultEnrollPath, enrollHandler).Methods("POST") - routerTLS.HandleFunc("/{environment}/"+environments.DefaultConfigPath, configHandler).Methods("POST") - routerTLS.HandleFunc("/{environment}/"+environments.DefaultLogPath, logHandler).Methods("POST") - routerTLS.HandleFunc("/{environment}/"+environments.DefaultQueryReadPath, queryReadHandler).Methods("POST") - routerTLS.HandleFunc("/{environment}/"+environments.DefaultQueryWritePath, queryWriteHandler).Methods("POST") - routerTLS.HandleFunc("/{environment}/"+environments.DefaultCarverInitPath, carveInitHandler).Methods("POST") - routerTLS.HandleFunc("/{environment}/"+environments.DefaultCarverBlockPath, carveBlockHandler).Methods("POST") - // TLS: Quick enroll/remove script - routerTLS.HandleFunc("/{environment}/{secretpath}/{script}", quickEnrollHandler).Methods("GET") - - // Ticker to reload environments + // Sleep to reload environments // FIXME Implement Redis cache // FIXME splay this? if settingsmgr.DebugService(settings.ServiceTLS) { - log.Println("DebugService: Environments ticker") + log.Println("DebugService: Environments refresher") } // Refresh environments as soon as service starts go refreshEnvironments() @@ -223,20 +198,17 @@ func main() { if _t == 0 { _t = int64(defaultRefresh) } - envsTicker = time.NewTicker(time.Duration(_t) * time.Second) for { - select { - case <-envsTicker.C: - go refreshEnvironments() - } + time.Sleep(time.Duration(_t) * time.Second) + go refreshEnvironments() } }() - // Ticker to reload settings + // Sleep to reload settings // FIXME Implement Redis cache // FIXME splay this? if settingsmgr.DebugService(settings.ServiceTLS) { - log.Println("DebugService: Settings ticker") + log.Println("DebugService: Settings refresher") } // Refresh settings as soon as the service starts go refreshSettings() @@ -245,15 +217,62 @@ func main() { if _t == 0 { _t = int64(defaultRefresh) } - settingsTicker = time.NewTicker(time.Duration(_t) * time.Second) for { - select { - case <-settingsTicker.C: - go refreshSettings() - } + time.Sleep(time.Duration(_t) * time.Second) + go refreshSettings() + } + }() + + // Initialize TLS handlers before router + handlersTLS = handlers.CreateHandlersTLS( + handlers.WithEnvs(envs), + handlers.WithEnvsMap(envsmap), + handlers.WithNodes(nodesmgr), + handlers.WithQueries(queriesmgr), + handlers.WithCarves(filecarves), + handlers.WithSettings(settingsmgr), + handlers.WithSettingsMap(settingsmap), + handlers.WithMetrics(_metrics), + handlers.WithLogs(loggerTLS), + ) + // Keeping maps updated in the handlers + go func() { + for { + time.Sleep(time.Duration(defaultMapRefresh) * time.Second) + handlersTLS.EnvsMap = envsmap + handlersTLS.SettingsMap = settingsmap } }() + /////////////////////////// ALL CONTENT IS UNAUTHENTICATED FOR TLS + if settingsmgr.DebugService(settings.ServiceTLS) { + log.Println("DebugService: Creating router") + } + // Create router for TLS endpoint + routerTLS := mux.NewRouter() + // TLS: root + routerTLS.HandleFunc("/", handlersTLS.RootHandler) + // TLS: testing + routerTLS.HandleFunc(healthPath, handlersTLS.HealthHandler).Methods("GET") + // TLS: error + routerTLS.HandleFunc(errorPath, handlersTLS.ErrorHandler).Methods("GET") + // TLS: Specific routes for osquery nodes + // FIXME this forces all paths to be the same + routerTLS.HandleFunc("/{environment}/"+environments.DefaultEnrollPath, handlersTLS.EnrollHandler).Methods("POST") + routerTLS.HandleFunc("/{environment}/"+environments.DefaultConfigPath, handlersTLS.ConfigHandler).Methods("POST") + routerTLS.HandleFunc("/{environment}/"+environments.DefaultLogPath, handlersTLS.LogHandler).Methods("POST") + routerTLS.HandleFunc("/{environment}/"+environments.DefaultQueryReadPath, handlersTLS.QueryReadHandler).Methods("POST") + routerTLS.HandleFunc("/{environment}/"+environments.DefaultQueryWritePath, handlersTLS.QueryWriteHandler).Methods("POST") + routerTLS.HandleFunc("/{environment}/"+environments.DefaultCarverInitPath, handlersTLS.CarveInitHandler).Methods("POST") + routerTLS.HandleFunc("/{environment}/"+environments.DefaultCarverBlockPath, handlersTLS.CarveBlockHandler).Methods("POST") + // TLS: Quick enroll/remove script + routerTLS.HandleFunc("/{environment}/{secretpath}/{script}", handlersTLS.QuickEnrollHandler).Methods("GET") + + //////////////////////////////// Everything is ready at this point! + + // multiple listeners channel + finish := make(chan bool) + // Launch HTTP server for TLS endpoint go func() { serviceListener := tlsConfig.Listener + ":" + tlsConfig.Port From 248cf59e5cce47e4c08ab4e369cd94c76b6d98fd Mon Sep 17 00:00:00 2001 From: Javier Marcos Date: Mon, 23 Mar 2020 23:11:01 -0700 Subject: [PATCH 2/3] Using pointers to maps --- Makefile | 25 ++------------ environments/environments.go | 2 +- logging/go.sum | 1 - nodes/go.sum | 10 ++++++ queries/go.mod | 3 -- tls/handlers/go.mod | 2 -- tls/handlers/go.sum | 6 ---- tls/handlers/handlers.go | 62 +++++++++++++++++------------------ tls/handlers/handlers_test.go | 40 ++++++++++++++++++++++ tls/main.go | 19 +++-------- tls/utils.go | 14 ++++---- types/go.mod | 4 --- 12 files changed, 97 insertions(+), 91 deletions(-) delete mode 100644 tls/handlers/go.sum create mode 100644 tls/handlers/handlers_test.go diff --git a/Makefile b/Makefile index a4e5e45d..71d3e823 100644 --- a/Makefile +++ b/Makefile @@ -182,27 +182,8 @@ gofmt-api: gofmt-cli: gofmt $(GOFMT_ARGS) ./$(CLI_CODE) -# Run tests for modules -modules-test: - cd utils && go test -i . -v - cd utils && go test . -v - # Run all tests test: - make modules-test - # Install dependencies for TLS - cd $(TLS_DIR) && go test -i . -v - # Run TLS tests - cd $(TLS_DIR) && go test . -v - # Install dependencies for Admin - cd $(ADMIN_DIR) && go test -i . -v - # Run Admin tests - cd $(ADMIN_DIR) && go test . -v - # Install dependencies for API - cd $(API_DIR) && go test -i . -v - # Run API tests - cd $(API_DIR) && go test . -v - # Install dependencies for CLI - cd $(CLI_DIR) && go test -i . -v - # Run CLI tests - cd $(CLI_DIR) && go test . -v + go clean -testcache ./... + go test ./utils -v + go test ./tls/handlers -v diff --git a/environments/environments.go b/environments/environments.go index 7333bfdc..4ba2b505 100644 --- a/environments/environments.go +++ b/environments/environments.go @@ -177,7 +177,7 @@ func (environment *Environment) Names() ([]string, error) { func (environment *Environment) GetMap() (MapEnvironments, error) { all, err := environment.All() if err != nil { - return MapEnvironments{}, fmt.Errorf("error getting environments %v", err) + return nil, fmt.Errorf("error getting environments %v", err) } _map := make(MapEnvironments) for _, e := range all { diff --git a/logging/go.sum b/logging/go.sum index c7d99e83..9707151f 100644 --- a/logging/go.sum +++ b/logging/go.sum @@ -48,7 +48,6 @@ github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmpsec/osctrl v0.1.9 h1:AyxqZs+XfTaqlsG/b54e2Rlh4mu2+oGd5cUUb1+K97k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= diff --git a/nodes/go.sum b/nodes/go.sum index cded202f..c37d64f6 100644 --- a/nodes/go.sum +++ b/nodes/go.sum @@ -1,5 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -10,14 +11,17 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02 h1:PS3xfVPa8N84AzoWZHFCbA0+ikz4f4skktfjQoNMsgk= github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -28,6 +32,7 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -40,13 +45,16 @@ github.com/jinzhu/gorm v1.9.8 h1:n5uvxqLepIP2R1XF7pudpt9Rv8I3m7G9trGxJVjLZ5k= github.com/jinzhu/gorm v1.9.8/go.mod h1:bdqTT3q6dhSph2K3pWxrHP6nqxuAp2yQ3KFtc3U3F84= github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k= github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.0 h1:6WV8LvwPpDhKjo5U9O6b4+xdG/jTXNPwlDme/MTo8Ns= github.com/jinzhu/now v1.0.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/lib/pq v1.1.0 h1:/5u4a+KGJptBRqGzPvYQL9p0d/tPR4S31+Tnzj9lEO4= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -71,6 +79,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -105,6 +114,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= diff --git a/queries/go.mod b/queries/go.mod index 60d44b3d..01f74eef 100644 --- a/queries/go.mod +++ b/queries/go.mod @@ -3,8 +3,5 @@ module github.com/jmpsec/osctrl/queries go 1.12 require ( - github.com/jmpsec/osctrl/nodes v0.1.9 github.com/jinzhu/gorm v1.9.8 ) - -replace github.com/jmpsec/osctrl/nodes => ../nodes diff --git a/tls/handlers/go.mod b/tls/handlers/go.mod index 884293de..d93064ae 100644 --- a/tls/handlers/go.mod +++ b/tls/handlers/go.mod @@ -1,5 +1,3 @@ module github.com/javuto/osctrl/tls/handlers go 1.12 - -require github.com/stretchr/testify v1.5.1 diff --git a/tls/handlers/go.sum b/tls/handlers/go.sum deleted file mode 100644 index fb52f53a..00000000 --- a/tls/handlers/go.sum +++ /dev/null @@ -1,6 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/tls/handlers/handlers.go b/tls/handlers/handlers.go index c3381642..8b3576ef 100644 --- a/tls/handlers/handlers.go +++ b/tls/handlers/handlers.go @@ -51,12 +51,12 @@ const ( // HandlersTLS to keep all handlers for TLS type HandlersTLS struct { Envs *environments.Environment - EnvsMap environments.MapEnvironments + EnvsMap *environments.MapEnvironments Nodes *nodes.NodeManager Queries *queries.Queries Carves *carves.Carves Settings *settings.Settings - SettingsMap settings.MapSettings + SettingsMap *settings.MapSettings Metrics *metrics.Metrics Logs *logging.LoggerTLS } @@ -69,39 +69,39 @@ func WithEnvs(envs *environments.Environment) HandlersOption { } } -func WithEnvsMap(envsmap environments.MapEnvironments) HandlersOption { +func WithEnvsMap(envsmap *environments.MapEnvironments) HandlersOption { return func(h *HandlersTLS) { h.EnvsMap = envsmap } } -func WithNodes(nodes *nodes.NodeManager) HandlersOption { +func WithSettings(settings *settings.Settings) HandlersOption { return func(h *HandlersTLS) { - h.Nodes = nodes + h.Settings = settings } } -func WithQueries(queries *queries.Queries) HandlersOption { +func WithSettingsMap(settingsmap *settings.MapSettings) HandlersOption { return func(h *HandlersTLS) { - h.Queries = queries + h.SettingsMap = settingsmap } } -func WithCarves(carves *carves.Carves) HandlersOption { +func WithNodes(nodes *nodes.NodeManager) HandlersOption { return func(h *HandlersTLS) { - h.Carves = carves + h.Nodes = nodes } } -func WithSettings(settings *settings.Settings) HandlersOption { +func WithQueries(queries *queries.Queries) HandlersOption { return func(h *HandlersTLS) { - h.Settings = settings + h.Queries = queries } } -func WithSettingsMap(settingsmap settings.MapSettings) HandlersOption { +func WithCarves(carves *carves.Carves) HandlersOption { return func(h *HandlersTLS) { - h.SettingsMap = settingsmap + h.Carves = carves } } @@ -171,7 +171,7 @@ func (h *HandlersTLS) EnrollHandler(w http.ResponseWriter, r *http.Request) { return } // Debug HTTP for environment - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Decode read POST body var t types.EnrollRequest err := json.NewDecoder(r.Body).Decode(&t) @@ -218,7 +218,7 @@ func (h *HandlersTLS) EnrollHandler(w http.ResponseWriter, r *http.Request) { } response := types.EnrollResponse{NodeKey: nodeKey, NodeInvalid: nodeInvalid} // Debug HTTP - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { log.Printf("Response: %+v", response) } // Serialize and send response @@ -245,7 +245,7 @@ func (h *HandlersTLS) ConfigHandler(w http.ResponseWriter, r *http.Request) { return } // Debug HTTP for environment - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Get environment e, err := h.Envs.Get(env) if err != nil { @@ -279,7 +279,7 @@ func (h *HandlersTLS) ConfigHandler(w http.ResponseWriter, r *http.Request) { response = types.ConfigResponse{NodeInvalid: true} } // Debug HTTP - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { if x, ok := response.([]byte); ok { log.Printf("Configuration: %s", string(x)) } else { @@ -326,7 +326,7 @@ func (h *HandlersTLS) LogHandler(w http.ResponseWriter, r *http.Request) { }() } // Debug HTTP here so the body will be uncompressed - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Extract POST body and decode JSON var t types.LogRequest err = json.NewDecoder(r.Body).Decode(&t) @@ -348,14 +348,14 @@ func (h *HandlersTLS) LogHandler(w http.ResponseWriter, r *http.Request) { if h.Nodes.CheckByKey(t.NodeKey) { nodeInvalid = false // Process logs and update metadata - h.Logs.ProcessLogs(t.Data, t.LogType, env, r.Header.Get("X-Real-IP"), h.EnvsMap[env].DebugHTTP) + h.Logs.ProcessLogs(t.Data, t.LogType, env, r.Header.Get("X-Real-IP"), (*h.EnvsMap)[env].DebugHTTP) } else { nodeInvalid = true } // Prepare response response := types.LogResponse{NodeInvalid: nodeInvalid} // Debug - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { log.Printf("Response: %+v", response) } // Serialize and send response @@ -381,7 +381,7 @@ func (h *HandlersTLS) QueryReadHandler(w http.ResponseWriter, r *http.Request) { return } // Debug HTTP - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Decode read POST body var t types.QueryReadRequest err := json.NewDecoder(r.Body).Decode(&t) @@ -419,13 +419,13 @@ func (h *HandlersTLS) QueryReadHandler(w http.ResponseWriter, r *http.Request) { // Prepare response and serialize queries var response interface{} if accelerate { - sAccelerate := int(h.SettingsMap[settings.AcceleratedSeconds].Integer) + sAccelerate := int((*h.SettingsMap)[settings.AcceleratedSeconds].Integer) response = types.AcceleratedQueryReadResponse{Queries: qs, Accelerate: sAccelerate, NodeInvalid: nodeInvalid} } else { response = types.QueryReadResponse{Queries: qs, NodeInvalid: nodeInvalid} } // Debug HTTP - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { log.Printf("Response: %+v", response) } // Serialize and send response @@ -451,7 +451,7 @@ func (h *HandlersTLS) QueryWriteHandler(w http.ResponseWriter, r *http.Request) return } // Debug HTTP - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Decode read POST body var t types.QueryWriteRequest err := json.NewDecoder(r.Body).Decode(&t) @@ -470,14 +470,14 @@ func (h *HandlersTLS) QueryWriteHandler(w http.ResponseWriter, r *http.Request) } nodeInvalid = false // Process submitted results - go h.Logs.ProcessLogQueryResult(t.Queries, t.Statuses, t.NodeKey, env, h.EnvsMap[env].DebugHTTP) + go h.Logs.ProcessLogQueryResult(t.Queries, t.Statuses, t.NodeKey, env, (*h.EnvsMap)[env].DebugHTTP) } else { nodeInvalid = true } // Prepare response response := types.QueryWriteResponse{NodeInvalid: nodeInvalid} // Debug HTTP - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { log.Printf("Response: %+v", response) } // Send response @@ -503,7 +503,7 @@ func (h *HandlersTLS) QuickEnrollHandler(w http.ResponseWriter, r *http.Request) return } // Debug HTTP - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) e, err := h.Envs.Get(env) if err != nil { h.Inc(metricOnelinerErr) @@ -570,7 +570,7 @@ func (h *HandlersTLS) CarveInitHandler(w http.ResponseWriter, r *http.Request) { return } // Debug HTTP - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Decode read POST body var t types.CarveInitRequest err := json.NewDecoder(r.Body).Decode(&t) @@ -600,7 +600,7 @@ func (h *HandlersTLS) CarveInitHandler(w http.ResponseWriter, r *http.Request) { // Prepare response response := types.CarveInitResponse{Success: initCarve, SessionID: carveSessionID} // Debug HTTP - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { log.Printf("Response: %+v", response) } // Send response @@ -626,7 +626,7 @@ func (h *HandlersTLS) CarveBlockHandler(w http.ResponseWriter, r *http.Request) return } // Debug HTTP - utils.DebugHTTPDump(r, h.EnvsMap[env].DebugHTTP, true) + utils.DebugHTTPDump(r, (*h.EnvsMap)[env].DebugHTTP, true) // Decode read POST body var t types.CarveBlockRequest err := json.NewDecoder(r.Body).Decode(&t) @@ -644,7 +644,7 @@ func (h *HandlersTLS) CarveBlockHandler(w http.ResponseWriter, r *http.Request) } // Prepare response response := types.CarveBlockResponse{Success: blockCarve} - if h.EnvsMap[env].DebugHTTP { + if (*h.EnvsMap)[env].DebugHTTP { log.Printf("Response: %+v", response) } // Send response diff --git a/tls/handlers/handlers_test.go b/tls/handlers/handlers_test.go new file mode 100644 index 00000000..59d330aa --- /dev/null +++ b/tls/handlers/handlers_test.go @@ -0,0 +1,40 @@ +package handlers + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRootHandler(t *testing.T) { + req, _ := http.NewRequest("GET", "/", nil) + h := CreateHandlersTLS() + rr := httptest.NewRecorder() + handler := http.HandlerFunc(h.RootHandler) + handler.ServeHTTP(rr, req) + assert.Equal(t, http.StatusOK, rr.Code) + assert.Equal(t, "💥", rr.Body.String()) +} + +func TestHealthHandler(t *testing.T) { + req, _ := http.NewRequest("GET", "/health", nil) + h := CreateHandlersTLS() + rr := httptest.NewRecorder() + handler := http.HandlerFunc(h.HealthHandler) + handler.ServeHTTP(rr, req) + assert.Equal(t, http.StatusOK, rr.Code) + assert.Equal(t, "✅", rr.Body.String()) +} + +func TestErrorHandler(t *testing.T) { + req, _ := http.NewRequest("GET", "/error", nil) + h := CreateHandlersTLS() + rr := httptest.NewRecorder() + handler := http.HandlerFunc(h.ErrorHandler) + handler.ServeHTTP(rr, req) + assert.Equal(t, http.StatusInternalServerError, rr.Code) + assert.Equal(t, "uh oh...", rr.Body.String()) +} + diff --git a/tls/main.go b/tls/main.go index 8d15e85c..6bd0b1a1 100644 --- a/tls/main.go +++ b/tls/main.go @@ -192,18 +192,16 @@ func main() { log.Println("DebugService: Environments refresher") } // Refresh environments as soon as service starts - go refreshEnvironments() go func() { _t := settingsmgr.RefreshEnvs(settings.ServiceTLS) if _t == 0 { _t = int64(defaultRefresh) } for { + envsmap = refreshEnvironments() time.Sleep(time.Duration(_t) * time.Second) - go refreshEnvironments() } }() - // Sleep to reload settings // FIXME Implement Redis cache // FIXME splay this? @@ -211,38 +209,29 @@ func main() { log.Println("DebugService: Settings refresher") } // Refresh settings as soon as the service starts - go refreshSettings() go func() { _t := settingsmgr.RefreshSettings(settings.ServiceTLS) if _t == 0 { _t = int64(defaultRefresh) } for { + settingsmap = refreshSettings() time.Sleep(time.Duration(_t) * time.Second) - go refreshSettings() } }() // Initialize TLS handlers before router handlersTLS = handlers.CreateHandlersTLS( handlers.WithEnvs(envs), - handlers.WithEnvsMap(envsmap), + handlers.WithEnvsMap(&envsmap), handlers.WithNodes(nodesmgr), handlers.WithQueries(queriesmgr), handlers.WithCarves(filecarves), handlers.WithSettings(settingsmgr), - handlers.WithSettingsMap(settingsmap), + handlers.WithSettingsMap(&settingsmap), handlers.WithMetrics(_metrics), handlers.WithLogs(loggerTLS), ) - // Keeping maps updated in the handlers - go func() { - for { - time.Sleep(time.Duration(defaultMapRefresh) * time.Second) - handlersTLS.EnvsMap = envsmap - handlersTLS.SettingsMap = settingsmap - } - }() /////////////////////////// ALL CONTENT IS UNAUTHENTICATED FOR TLS if settingsmgr.DebugService(settings.ServiceTLS) { diff --git a/tls/utils.go b/tls/utils.go index e70ec87c..2feee1f9 100644 --- a/tls/utils.go +++ b/tls/utils.go @@ -148,23 +148,25 @@ func incMetric(name string) { } // Helper to refresh the environments map until cache/Redis support is implemented -func refreshEnvironments() { +func refreshEnvironments() environments.MapEnvironments { log.Printf("Refreshing environments...\n") - var err error - envsmap, err = envs.GetMap() + _envsmap, err := envs.GetMap() if err != nil { log.Printf("error refreshing environments %v\n", err) + return environments.MapEnvironments{} } + return _envsmap } // Helper to refresh the settings until cache/Redis support is implemented -func refreshSettings() { +func refreshSettings() settings.MapSettings { log.Printf("Refreshing settings...\n") - var err error - settingsmap, err = settingsmgr.GetMap(settings.ServiceTLS) + _settingsmap, err := settingsmgr.GetMap(settings.ServiceTLS) if err != nil { log.Printf("error refreshing settings %v\n", err) + return settings.MapSettings{} } + return _settingsmap } // Usage for service binary diff --git a/types/go.mod b/types/go.mod index bdb967dd..0885823e 100644 --- a/types/go.mod +++ b/types/go.mod @@ -1,7 +1,3 @@ module github.com/jmpsec/osctrl/types go 1.12 - -require github.com/jmpsec/osctrl/queries v0.1.9 - -replace github.com/jmpsec/osctrl/queries => ../queries From 8112ce90ace03a4789e658f7b54e1061a9fcd0ab Mon Sep 17 00:00:00 2001 From: Javier Marcos Date: Wed, 25 Mar 2020 19:21:31 -0700 Subject: [PATCH 3/3] Adding more tests --- .travis.yml | 2 + go.mod | 5 +- go.sum | 1 - queries/go.mod | 1 + queries/go.sum | 135 ++++++++++++++++++++++++++++++++++ tls/handlers/go.mod | 2 + tls/handlers/go.sum | 125 +++++++++++++++++++++++++++++++ tls/handlers/handlers.go | 3 +- tls/handlers/handlers_test.go | 1 - tls/handlers/utils.go | 13 ++-- tls/handlers/utils_test.go | 104 ++++++++++++++++++++++++++ tls/utils.go | 107 --------------------------- 12 files changed, 380 insertions(+), 119 deletions(-) create mode 100644 queries/go.sum create mode 100644 tls/handlers/go.sum create mode 100644 tls/handlers/utils_test.go diff --git a/.travis.yml b/.travis.yml index 74bce339..3bb31892 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,3 +18,5 @@ script: - go build -o bin/osctrl-tls tls/*.go - go build -o bin/osctrl-admin admin/*.go - go build -o bin/osctrl-cli cli/*.go + - go test ./utils -v + - go test ./tls/handlers -v diff --git a/go.mod b/go.mod index 7a6b8628..d272fee8 100644 --- a/go.mod +++ b/go.mod @@ -16,8 +16,8 @@ require ( github.com/jmpsec/osctrl/environments v0.2.1 github.com/jmpsec/osctrl/logging v0.2.1 github.com/jmpsec/osctrl/metrics v0.2.1 - github.com/jmpsec/osctrl/nodes v0.2.1 - github.com/jmpsec/osctrl/queries v0.2.1 + github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4 + github.com/jmpsec/osctrl/queries v0.0.0-20200321003619-c21be7214ee4 github.com/jmpsec/osctrl/settings v0.2.1 github.com/jmpsec/osctrl/tls/handlers v0.2.1 github.com/jmpsec/osctrl/types v0.2.1 @@ -26,7 +26,6 @@ require ( github.com/mattn/go-runewidth v0.0.4 // indirect github.com/olekukonko/tablewriter v0.0.1 github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7 // indirect - github.com/segmentio/ksuid v1.0.2 github.com/spf13/viper v1.6.2 github.com/urfave/cli v1.20.0 ) diff --git a/go.sum b/go.sum index 40a1988d..7200ae73 100644 --- a/go.sum +++ b/go.sum @@ -174,7 +174,6 @@ github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= diff --git a/queries/go.mod b/queries/go.mod index 01f74eef..5314703e 100644 --- a/queries/go.mod +++ b/queries/go.mod @@ -4,4 +4,5 @@ go 1.12 require ( github.com/jinzhu/gorm v1.9.8 + github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4 ) diff --git a/queries/go.sum b/queries/go.sum new file mode 100644 index 00000000..1c739454 --- /dev/null +++ b/queries/go.sum @@ -0,0 +1,135 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= +cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02 h1:PS3xfVPa8N84AzoWZHFCbA0+ikz4f4skktfjQoNMsgk= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jinzhu/gorm v1.9.8 h1:n5uvxqLepIP2R1XF7pudpt9Rv8I3m7G9trGxJVjLZ5k= +github.com/jinzhu/gorm v1.9.8/go.mod h1:bdqTT3q6dhSph2K3pWxrHP6nqxuAp2yQ3KFtc3U3F84= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.0 h1:6WV8LvwPpDhKjo5U9O6b4+xdG/jTXNPwlDme/MTo8Ns= +github.com/jinzhu/now v1.0.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= +github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4 h1:E2HUseTq4nCI0H9o3RYQo1BP/YAegllbLDkT6E56u6M= +github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4/go.mod h1:o8iBR3e+m2Rxaf8tnIWSVtKieL7UenN2NjidHclvoII= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/lib/pq v1.1.0 h1:/5u4a+KGJptBRqGzPvYQL9p0d/tPR4S31+Tnzj9lEO4= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tls/handlers/go.mod b/tls/handlers/go.mod index d93064ae..312ad259 100644 --- a/tls/handlers/go.mod +++ b/tls/handlers/go.mod @@ -1,3 +1,5 @@ module github.com/javuto/osctrl/tls/handlers go 1.12 + +require github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4 // indirect diff --git a/tls/handlers/go.sum b/tls/handlers/go.sum new file mode 100644 index 00000000..0b2231ba --- /dev/null +++ b/tls/handlers/go.sum @@ -0,0 +1,125 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jinzhu/gorm v1.9.8 h1:n5uvxqLepIP2R1XF7pudpt9Rv8I3m7G9trGxJVjLZ5k= +github.com/jinzhu/gorm v1.9.8/go.mod h1:bdqTT3q6dhSph2K3pWxrHP6nqxuAp2yQ3KFtc3U3F84= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYXJi4pg1ZKM7nxc5AfXfojeLLW7O5J3k= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= +github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4 h1:E2HUseTq4nCI0H9o3RYQo1BP/YAegllbLDkT6E56u6M= +github.com/jmpsec/osctrl/nodes v0.0.0-20200321003619-c21be7214ee4/go.mod h1:o8iBR3e+m2Rxaf8tnIWSVtKieL7UenN2NjidHclvoII= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tls/handlers/handlers.go b/tls/handlers/handlers.go index 8b3576ef..5a8dbb1f 100644 --- a/tls/handlers/handlers.go +++ b/tls/handlers/handlers.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "strings" + "time" "github.com/gorilla/mux" "github.com/jmpsec/osctrl/carves" @@ -186,7 +187,7 @@ func (h *HandlersTLS) EnrollHandler(w http.ResponseWriter, r *http.Request) { nodeInvalid := true if h.checkValidSecret(t.EnrollSecret, env) { // Generate node_key using UUID as entropy - nodeKey = generateNodeKey(t.HostIdentifier) + nodeKey = generateNodeKey(t.HostIdentifier, time.Now()) newNode = nodeFromEnroll(t, env, r.Header.Get("X-Real-IP"), nodeKey) // Check if UUID exists already, if so archive node and enroll new node if h.Nodes.CheckByUUID(t.HostIdentifier) { diff --git a/tls/handlers/handlers_test.go b/tls/handlers/handlers_test.go index 59d330aa..ff8ac1db 100644 --- a/tls/handlers/handlers_test.go +++ b/tls/handlers/handlers_test.go @@ -37,4 +37,3 @@ func TestErrorHandler(t *testing.T) { assert.Equal(t, http.StatusInternalServerError, rr.Code) assert.Equal(t, "uh oh...", rr.Body.String()) } - diff --git a/tls/handlers/utils.go b/tls/handlers/utils.go index 9ba6c0b4..465c4298 100644 --- a/tls/handlers/utils.go +++ b/tls/handlers/utils.go @@ -2,9 +2,9 @@ package handlers import ( "bytes" - "crypto/md5" - "encoding/hex" + "crypto/sha1" "encoding/json" + "fmt" "log" "strconv" "strings" @@ -17,11 +17,12 @@ import ( ) // Helper to generate a random enough node key -func generateNodeKey(uuid string) string { - timestamp := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) - hasher := md5.New() +func generateNodeKey(uuid string, ts time.Time) string { + timestamp := strconv.FormatInt(ts.UTC().UnixNano(), 10) + hasher := sha1.New() _, _ = hasher.Write([]byte(uuid + timestamp)) - return hex.EncodeToString(hasher.Sum(nil)) + bs := hasher.Sum(nil) + return fmt.Sprintf("%x", bs) } // Helper to generate a carve session_id using KSUID diff --git a/tls/handlers/utils_test.go b/tls/handlers/utils_test.go new file mode 100644 index 00000000..327f44e6 --- /dev/null +++ b/tls/handlers/utils_test.go @@ -0,0 +1,104 @@ +package handlers + +import ( + "encoding/json" + "testing" + "time" + + "github.com/jmpsec/osctrl/nodes" + "github.com/jmpsec/osctrl/types" + "github.com/stretchr/testify/assert" +) + +func TestGenerateNodeKey(t *testing.T) { + ts := time.Date(2019, 9, 17, 20, 34, 58, 0, time.UTC) + _hash := "4d42e1adfb9a4d3e1b02be5370b5d1668c49d970" + nodekey := generateNodeKey("test", ts) + assert.Equal(t, _hash, nodekey) +} + +func TestGenerateCarveSessionID(t *testing.T) { + first := generateCarveSessionID() + second := generateCarveSessionID() + assert.NotEqual(t, first, second) +} + +func TestNodeFromEnroll(t *testing.T) { + _env := "testing" + _ip := "1.2.3.4" + _key := "node-key" + req := types.EnrollRequest{ + EnrollSecret: "secret", + HostIdentifier: "thisistheuuid", + PlatformType: "platform_type", + } + req.HostDetails.EnrollOSVersion = types.OSVersionTable{ + ID: "", + Codename: "", + Major: "", + Minor: "", + Name: "", + Patch: "", + Platform: "", + PlatformLike: "", + Version: "", + } + req.HostDetails.EnrollOsqueryInfo = types.OsqueryInfoTable{ + BuildDistro: "", + BuildPlatform: "", + ConfigHash: "", + ConfigValid: "", + Extension: "", + InstanceID: "", + PID: "", + StartTime: "", + UUID: "", + Version: "", + Watcher: "", + } + req.HostDetails.EnrollSystemInfo = types.SystemInfoTable{ + ComputerName: "", + CPUBrand: "", + CPULogicalCores: "", + CPUPhysicalCores: "", + CPUSubtype: "", + CPUType: "", + HardwareModel: "", + HardwareSerial: "", + HardwareVendor: "", + HardwareVersion: "", + Hostname: "", + LocalHostname: "", + PhysicalMemory: "memory", + UUID: "", + } + req.HostDetails.EnrollPlatformInfo = types.PlatformInfoTable{ + Address: "", + Date: "", + Extra: "", + Revision: "", + Size: "", + Vendor: "", + Version: "", + VolumeSize: "", + } + enrollRaw, _ := json.Marshal(req) + node := nodes.OsqueryNode{ + UUID: "THISISTHEUUID", + Environment: _env, + IPAddress: _ip, + NodeKey: _key, + Username: "unknown", + OsqueryUser: "unknown", + Memory: "memory", + RawEnrollment: enrollRaw, + } + resultNode := nodeFromEnroll(req, _env, _ip, _key) + assert.Equal(t, node, resultNode) +} + +func TestUniq(t *testing.T) { + aa := uniq([]string{"a", "a", "b", "b", "b", "c"}) + bb := []string{"a", "b", "c"} + assert.Equal(t, bb, aa) +} diff --git a/tls/utils.go b/tls/utils.go index 2feee1f9..b5ed022f 100644 --- a/tls/utils.go +++ b/tls/utils.go @@ -1,115 +1,15 @@ package main import ( - "bytes" - "crypto/md5" - "encoding/hex" - "encoding/json" "flag" "fmt" "log" "os" - "strconv" - "strings" - "time" "github.com/jmpsec/osctrl/environments" - "github.com/jmpsec/osctrl/nodes" - "github.com/jmpsec/osctrl/types" "github.com/jmpsec/osctrl/settings" - "github.com/segmentio/ksuid" ) -// Helper to generate a random enough node key -func generateNodeKey(uuid string) string { - timestamp := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) - hasher := md5.New() - _, _ = hasher.Write([]byte(uuid + timestamp)) - return hex.EncodeToString(hasher.Sum(nil)) -} - -// Helper to generate a carve session_id using KSUID -// See https://github.com/segmentio/ksuid for more info about KSUIDs -func generateCarveSessionID() string { - id := ksuid.New() - return id.String() -} - -// Helper to check if the provided secret is valid for this environment -func checkValidSecret(enrollSecret string, environment string) bool { - env, err := envs.Get(environment) - if err != nil { - return false - } - return (strings.TrimSpace(enrollSecret) == env.Secret) -} - -// Helper to check if the provided SecretPath is valid for enrolling in a environment -func checkValidEnrollSecretPath(environment, secretpath string) bool { - env, err := envs.Get(environment) - if err != nil { - return false - } - return ((strings.TrimSpace(secretpath) == env.EnrollSecretPath) && (!environments.IsItExpired(env.EnrollExpire))) -} - -// Helper to check if the provided SecretPath is valid for removing in a environment -func checkValidRemoveSecretPath(environment, secretpath string) bool { - env, err := envs.Get(environment) - if err != nil { - return false - } - return ((strings.TrimSpace(secretpath) == env.RemoveSecretPath) && (!environments.IsItExpired(env.RemoveExpire))) -} - -// Helper to convert an enrollment request into a osquery node -func nodeFromEnroll(req types.EnrollRequest, environment, ipaddress, nodekey string) nodes.OsqueryNode { - // Prepare the enrollment request to be stored as raw JSON - enrollRaw, err := json.Marshal(req) - if err != nil { - log.Printf("error serializing enrollment: %v", err) - enrollRaw = []byte("") - } - // Avoid the error "unsupported Unicode escape sequence" due to \u0000 - enrollRaw = bytes.Replace(enrollRaw, []byte("\\u0000"), []byte(""), -1) - return nodes.OsqueryNode{ - NodeKey: nodekey, - UUID: strings.ToUpper(req.HostIdentifier), - Platform: req.HostDetails.EnrollOSVersion.Platform, - PlatformVersion: req.HostDetails.EnrollOSVersion.Version, - OsqueryVersion: req.HostDetails.EnrollOsqueryInfo.Version, - Hostname: req.HostDetails.EnrollSystemInfo.Hostname, - Localname: req.HostDetails.EnrollSystemInfo.LocalHostname, - IPAddress: ipaddress, - Username: "unknown", - OsqueryUser: "unknown", - Environment: environment, - CPU: strings.TrimRight(req.HostDetails.EnrollSystemInfo.CPUBrand, "\x00"), - Memory: req.HostDetails.EnrollSystemInfo.PhysicalMemory, - HardwareSerial: req.HostDetails.EnrollSystemInfo.HardwareSerial, - ConfigHash: req.HostDetails.EnrollOsqueryInfo.ConfigHash, - RawEnrollment: enrollRaw, - LastStatus: time.Time{}, - LastResult: time.Time{}, - LastConfig: time.Time{}, - LastQueryRead: time.Time{}, - LastQueryWrite: time.Time{}, - } -} - -// Helper to remove duplicates from array of strings -func uniq(duplicated []string) []string { - keys := make(map[string]bool) - result := []string{} - for _, entry := range duplicated { - if _, value := keys[entry]; !value { - keys[entry] = true - result = append(result, entry) - } - } - return result -} - // Helper to determine if an IPv4 is public, based on the following: // Class Starting IPAddress Ending IPAddress // A 10.0.0.0 10.255.255.255 @@ -140,13 +40,6 @@ func isPublicIP(ip net.IP) bool { } */ -// Helper to send metrics if it is enabled -func incMetric(name string) { - if _metrics != nil && settingsmgr.ServiceMetrics(settings.ServiceTLS) { - _metrics.Inc(name) - } -} - // Helper to refresh the environments map until cache/Redis support is implemented func refreshEnvironments() environments.MapEnvironments { log.Printf("Refreshing environments...\n")