diff --git a/nettests/groups/groups.go b/nettests/groups/groups.go index 091c7b3..9a1df41 100644 --- a/nettests/groups/groups.go +++ b/nettests/groups/groups.go @@ -6,6 +6,8 @@ import ( "github.com/apex/log" "github.com/openobservatory/gooni/internal/database" "github.com/openobservatory/gooni/nettests" + "github.com/openobservatory/gooni/nettests/im" + "github.com/openobservatory/gooni/nettests/middlebox" "github.com/openobservatory/gooni/nettests/performance" "github.com/openobservatory/gooni/nettests/websites" ) @@ -25,6 +27,16 @@ type PerformanceSummary struct { Bitrate int64 } +// MiddleboxSummary is the summary for the middlebox tests +type MiddleboxSummary struct { + Detected bool +} + +// IMSummary is the summary for the im tests +type IMSummary struct { + Detected bool +} + // NettestGroups that can be run by the user var NettestGroups = map[string]NettestGroup{ "websites": NettestGroup{ @@ -71,15 +83,43 @@ var NettestGroups = map[string]NettestGroup{ }, }, "middleboxes": NettestGroup{ - Label: "Middleboxes", - Nettests: []nettests.Nettest{}, + Label: "Middleboxes", + Nettests: []nettests.Nettest{ + middlebox.HTTPInvalidRequestLine{}, + middlebox.HTTPHeaderFieldManipulation{}, + }, Summary: func(m database.SummaryMap) (string, error) { - return "{}", nil + var ( + err error + hhfmSummary middlebox.HTTPHeaderFieldManipulationSummary + hirlSummary middlebox.HTTPInvalidRequestLineSummary + summary MiddleboxSummary + ) + err = json.Unmarshal([]byte(m["HttpHeaderFieldManipulation"]), &hhfmSummary) + if err != nil { + log.WithError(err).Error("failed to unmarshal hhfm summary") + return "", err + } + err = json.Unmarshal([]byte(m["HttpInvalidRequestLine"]), &hirlSummary) + if err != nil { + log.WithError(err).Error("failed to unmarshal hirl summary") + return "", err + } + summary.Detected = hirlSummary.Tampering == true || hhfmSummary.Tampering == true + summaryBytes, err := json.Marshal(summary) + if err != nil { + return "", err + } + return string(summaryBytes), nil }, }, "im": NettestGroup{ - Label: "Instant Messaging", - Nettests: []nettests.Nettest{}, + Label: "Instant Messaging", + Nettests: []nettests.Nettest{ + im.FacebookMessenger{}, + im.Telegram{}, + im.WhatsApp{}, + }, Summary: func(m database.SummaryMap) (string, error) { return "{}", nil }, diff --git a/nettests/im/facebook_messenger.go b/nettests/im/facebook_messenger.go new file mode 100644 index 0000000..bb7fcac --- /dev/null +++ b/nettests/im/facebook_messenger.go @@ -0,0 +1,36 @@ +package im + +import ( + "github.com/measurement-kit/go-measurement-kit" + "github.com/openobservatory/gooni/nettests" +) + +// FacebookMessenger test implementation +type FacebookMessenger struct { +} + +// Run starts the test +func (h FacebookMessenger) Run(ctl *nettests.Controller) error { + mknt := mk.NewNettest("FacebookMessenger") + ctl.Init(mknt) + return mknt.Run() +} + +// FacebookMessengerSummary for the test +type FacebookMessengerSummary struct { + DNSBlocking bool + TCPBlocking bool +} + +// Summary generates a summary for a test run +func (h FacebookMessenger) Summary(tk map[string]interface{}) interface{} { + return FacebookMessengerSummary{ + DNSBlocking: tk["facebook_dns_blocking"].(bool), + TCPBlocking: tk["facebook_tcp_blocking"].(bool), + } +} + +// LogSummary writes the summary to the standard output +func (h FacebookMessenger) LogSummary(s string) error { + return nil +} diff --git a/nettests/im/telegram.go b/nettests/im/telegram.go new file mode 100644 index 0000000..503d55c --- /dev/null +++ b/nettests/im/telegram.go @@ -0,0 +1,38 @@ +package im + +import ( + "github.com/measurement-kit/go-measurement-kit" + "github.com/openobservatory/gooni/nettests" +) + +// Telegram test implementation +type Telegram struct { +} + +// Run starts the test +func (h Telegram) Run(ctl *nettests.Controller) error { + mknt := mk.NewNettest("Telegram") + ctl.Init(mknt) + return mknt.Run() +} + +// TelegramSummary for the test +type TelegramSummary struct { + HTTPBlocking bool + TCPBlocking bool + WebBlocking bool +} + +// Summary generates a summary for a test run +func (h Telegram) Summary(tk map[string]interface{}) interface{} { + return TelegramSummary{ + TCPBlocking: tk["telegram_tcp_blocking"].(bool) == true, + HTTPBlocking: tk["telegram_http_blocking"].(bool) == true, + WebBlocking: tk["telegram_web_status"].(string) == "blocked", + } +} + +// LogSummary writes the summary to the standard output +func (h Telegram) LogSummary(s string) error { + return nil +} diff --git a/nettests/im/whatsapp.go b/nettests/im/whatsapp.go new file mode 100644 index 0000000..5dc26ba --- /dev/null +++ b/nettests/im/whatsapp.go @@ -0,0 +1,40 @@ +package im + +import ( + "github.com/measurement-kit/go-measurement-kit" + "github.com/openobservatory/gooni/nettests" +) + +// WhatsApp test implementation +type WhatsApp struct { +} + +// Run starts the test +func (h WhatsApp) Run(ctl *nettests.Controller) error { + mknt := mk.NewNettest("Whatsapp") + ctl.Init(mknt) + return mknt.Run() +} + +// WhatsAppSummary for the test +type WhatsAppSummary struct { + RegistrationServerBlocking bool + WebBlocking bool + EndpointsBlocking bool +} + +// Summary generates a summary for a test run +func (h WhatsApp) Summary(tk map[string]interface{}) interface{} { + const blk = "blocked" + + return WhatsAppSummary{ + RegistrationServerBlocking: tk["registration_server_status"].(string) == blk, + WebBlocking: tk["whatsapp_web_status"].(string) == blk, + EndpointsBlocking: tk["whatsapp_endpoints_status"].(string) == blk, + } +} + +// LogSummary writes the summary to the standard output +func (h WhatsApp) LogSummary(s string) error { + return nil +} diff --git a/nettests/middlebox/http_header_field_manipulation.go b/nettests/middlebox/http_header_field_manipulation.go new file mode 100644 index 0000000..c416985 --- /dev/null +++ b/nettests/middlebox/http_header_field_manipulation.go @@ -0,0 +1,43 @@ +package middlebox + +import ( + "github.com/measurement-kit/go-measurement-kit" + "github.com/openobservatory/gooni/nettests" +) + +// HTTPHeaderFieldManipulation test implementation +type HTTPHeaderFieldManipulation struct { +} + +// Run starts the test +func (h HTTPHeaderFieldManipulation) Run(ctl *nettests.Controller) error { + mknt := mk.NewNettest("HttpHeaderFieldManipulation") + ctl.Init(mknt) + return mknt.Run() +} + +// HTTPHeaderFieldManipulationSummary for the test +type HTTPHeaderFieldManipulationSummary struct { + Tampering bool +} + +// Summary generates a summary for a test run +func (h HTTPHeaderFieldManipulation) Summary(tk map[string]interface{}) interface{} { + tampering := false + for _, v := range tk["tampering"].(map[string]interface{}) { + t, ok := v.(bool) + // Ignore non booleans in the tampering map + if ok && t == true { + tampering = true + } + } + + return HTTPHeaderFieldManipulationSummary{ + Tampering: tampering, + } +} + +// LogSummary writes the summary to the standard output +func (h HTTPHeaderFieldManipulation) LogSummary(s string) error { + return nil +} diff --git a/nettests/middlebox/http_invalid_request_line.go b/nettests/middlebox/http_invalid_request_line.go new file mode 100644 index 0000000..8300fa1 --- /dev/null +++ b/nettests/middlebox/http_invalid_request_line.go @@ -0,0 +1,36 @@ +package middlebox + +import ( + "github.com/measurement-kit/go-measurement-kit" + "github.com/openobservatory/gooni/nettests" +) + +// HTTPInvalidRequestLine test implementation +type HTTPInvalidRequestLine struct { +} + +// Run starts the test +func (h HTTPInvalidRequestLine) Run(ctl *nettests.Controller) error { + mknt := mk.NewNettest("HttpInvalidRequestLine") + ctl.Init(mknt) + return mknt.Run() +} + +// HTTPInvalidRequestLineSummary for the test +type HTTPInvalidRequestLineSummary struct { + Tampering bool +} + +// Summary generates a summary for a test run +func (h HTTPInvalidRequestLine) Summary(tk map[string]interface{}) interface{} { + tampering := tk["tampering"].(bool) + + return HTTPInvalidRequestLineSummary{ + Tampering: tampering, + } +} + +// LogSummary writes the summary to the standard output +func (h HTTPInvalidRequestLine) LogSummary(s string) error { + return nil +}