diff --git a/attack.go b/attack.go index d8fa9ea..92fa5b5 100644 --- a/attack.go +++ b/attack.go @@ -32,6 +32,8 @@ func routeAttack(c Curler, camera Stream, route string, timeout time.Duration, e c.Setopt(curl.OPT_WRITEFUNCTION, doNotWrite) } + // Do not use signals (would break multithreading) + c.Setopt(curl.OPT_NOSIGNAL, 1) // Do not send a body in the describe request c.Setopt(curl.OPT_NOBODY, 1) // Send a request to the URL of the camera we want to attack @@ -82,6 +84,8 @@ func credAttack(c Curler, camera Stream, username string, password string, timeo c.Setopt(curl.OPT_WRITEFUNCTION, doNotWrite) } + // Do not use signals (would break multithreading) + c.Setopt(curl.OPT_NOSIGNAL, 1) // Do not send a body in the describe request c.Setopt(curl.OPT_NOBODY, 1) // Send a request to the URL of the camera we want to attack @@ -117,7 +121,7 @@ func credAttack(c Curler, camera Stream, username string, password string, timeo func attackCameraCredentials(c Curler, target Stream, credentials Credentials, resultsChan chan<- Stream, timeout time.Duration, log bool) { for _, username := range credentials.Usernames { for _, password := range credentials.Passwords { - ok := credAttack(c, target, username, password, timeout, log) + ok := credAttack(c.Duphandle(), target, username, password, timeout, log) if ok { target.CredentialsFound = true target.Username = username @@ -133,7 +137,7 @@ func attackCameraCredentials(c Curler, target Stream, credentials Credentials, r func attackCameraRoute(c Curler, target Stream, routes Routes, resultsChan chan<- Stream, timeout time.Duration, log bool) { for _, route := range routes { - ok := routeAttack(c, target, route, timeout, log) + ok := routeAttack(c.Duphandle(), target, route, timeout, log) if ok { target.RouteFound = true target.Route = route diff --git a/attack_test.go b/attack_test.go index b8e573d..fd60f2f 100644 --- a/attack_test.go +++ b/attack_test.go @@ -31,6 +31,10 @@ func (m *CurlerMock) Getinfo(info curl.CurlInfo) (interface{}, error) { return args.Int(0), args.Error(1) } +func (m *CurlerMock) Duphandle() Curler { + return m +} + func TestAttackCredentials(t *testing.T) { validStream1 := Stream{ Device: "fakeDevice", diff --git a/cameradar/cameradar.go b/cameradar/cameradar.go index b90d05b..ad78d3c 100644 --- a/cameradar/cameradar.go +++ b/cameradar/cameradar.go @@ -94,10 +94,11 @@ func main() { w := startSpinner(options.EnableLogs) err = curl.GlobalInit(curl.GLOBAL_ALL) - c := curl.EasyInit() - if err != nil || c == nil { + handle := curl.EasyInit() + if err != nil || handle == nil { printErr(errors.New("libcurl initialization failed")) } + c := &cmrdr.Curl{CURL: handle} defer curl.GlobalCleanup() updateSpinner(w, "Loading dictionaries...", options.EnableLogs) diff --git a/curl.go b/curl.go index 9b837b9..64782f2 100644 --- a/curl.go +++ b/curl.go @@ -10,4 +10,16 @@ type Curler interface { Setopt(opt int, param interface{}) error Perform() error Getinfo(info curl.CurlInfo) (interface{}, error) + Duphandle() Curler +} + +// Curl is a libcurl wrapper used to make the Curler interface work even though +// golang currently does not support covariance (see https://github.com/golang/go/issues/7512) +type Curl struct { + *curl.CURL +} + +// Duphandle wraps curl.Duphandle +func (c *Curl) Duphandle() Curler { + return &Curl{c.CURL.Duphandle()} }