diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..fa12ff6 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/pauldotknopf/goidevice + +go 1.16 + +require ( + github.com/mattn/go-pointer v0.0.1 + github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f20564e --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee h1:IquUs3fIykn10zWDIyddanhpTqBvAHMaPnFhQuyYw5U= +github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee/go.mod h1:eT2/Pcsim3XBjbvldGiJBvvgiqZkAFyiOJJsDKXs/ts= diff --git a/idevice/errors.go b/idevice/errors.go index 4fcf1e7..a890215 100644 --- a/idevice/errors.go +++ b/idevice/errors.go @@ -21,6 +21,72 @@ var ( ErrBadHeader = errors.New("bad header") // ErrSslError . ErrSslError = errors.New("ssl error") + // ErrReceiveTimeout . + ErrReceiveTimeout = errors.New("receive timeout") + // ErrMuxError . + ErrMuxError = errors.New("mux error") + // ErrNoRunningSession . + ErrNoRunningSession = errors.New("no running session") + // ErrInvalidResponse . + ErrInvalidResponse = errors.New("invalid response") + // ErrMissingKey . + ErrMissingKey = errors.New("missing key") + // ErrMissingValue . + ErrMissingValue = errors.New("missing value") + // ErrGetProhibited . + ErrGetProhibited = errors.New("get prohibited") + // ErrSetProhibited . + ErrSetProhibited = errors.New("set prohibited") + // ErrRemoveProhibited . + ErrRemoveProhibited = errors.New("remove prohibited") + // ErrImmutableValue . + ErrImmutableValue = errors.New("immutable value") + // ErrPasswordProtected . + ErrPasswordProtected = errors.New("password protected") + // ErrUserDeniedPairing . + ErrUserDeniedPairing = errors.New("user denied pairing") + // ErrPairingDialogResponsePending . + ErrPairingDialogResponsePending = errors.New("pairing dialog response pending") + // ErrMissingHostID . + ErrMissingHostID = errors.New("missing host id") + // ErrInvalidHostID . + ErrInvalidHostID = errors.New("invalid host id") + // ErrSessionActive . + ErrSessionActive = errors.New("session active") + // ErrSessionInactive . + ErrSessionInactive = errors.New("session inactive") + // ErrMissingSessionID . + ErrMissingSessionID = errors.New("missing session id") + // ErrInvalidSessionID . + ErrInvalidSessionID = errors.New("invalid session id") + // ErrMissingService . + ErrMissingService = errors.New("missing service") + // ErrInvalidService . + ErrInvalidService = errors.New("invalid service") + // ErrServiceLimit . + ErrServiceLimit = errors.New("service limit") + // ErrMissingPairRecord . + ErrMissingPairRecord = errors.New("missing pair record") + // ErrSavePairRecordFailed . + ErrSavePairRecordFailed = errors.New("save pair record failed") + // ErrInvalidPairRecord . + ErrInvalidPairRecord = errors.New("invalid pair record") + // ErrInvalidActivationPeriod . + ErrInvalidActivationPeriod = errors.New("invalid activation period") + // ErrMissingActivationPeriod . + ErrMissingActivationPeriod = errors.New("missing activation period") + // ErrServiceProhibited . + ErrServiceProhibited = errors.New("service prohibited") + // ErrEscrowLocked . + ErrEscrowLocked = errors.New("escrow locked") + // ErrPairingProhibitedOverThisConnection . + ErrPairingProhibitedOverThisConnection = errors.New("pairing prohibited over this connection") + // ErrFMIPProtected . + ErrFMIPProtected = errors.New("FMIP protected") + // ErrMCProtected . + ErrMCProtected = errors.New("MC Protected") + // ErrMCChallengeRequired . + ErrMCChallengeRequired = errors.New("mc challenge required") ) func resultToError(result C.idevice_error_t) error { @@ -39,6 +105,72 @@ func resultToError(result C.idevice_error_t) error { return ErrBadHeader case -6: return ErrSslError + case -7: + return ErrReceiveTimeout + case -8: + return ErrMuxError + case -9: + return ErrNoRunningSession + case -10: + return ErrInvalidResponse + case -11: + return ErrMissingKey + case -12: + return ErrMissingValue + case -13: + return ErrGetProhibited + case -14: + return ErrSetProhibited + case -15: + return ErrRemoveProhibited + case -16: + return ErrImmutableValue + case -17: + return ErrPasswordProtected + case -18: + return ErrUserDeniedPairing + case -19: + return ErrPairingDialogResponsePending + case -20: + return ErrMissingHostID + case -21: + return ErrInvalidHostID + case -22: + return ErrSessionActive + case -23: + return ErrSessionInactive + case -24: + return ErrMissingSessionID + case -25: + return ErrInvalidSessionID + case -26: + return ErrMissingService + case -27: + return ErrInvalidService + case -28: + return ErrServiceLimit + case -29: + return ErrMissingPairRecord + case -30: + return ErrSavePairRecordFailed + case -31: + return ErrInvalidPairRecord + case -32: + return ErrInvalidActivationPeriod + case -33: + return ErrMissingActivationPeriod + case -34: + return ErrServiceProhibited + case -35: + return ErrEscrowLocked + case -36: + return ErrPairingProhibitedOverThisConnection + case -37: + return ErrFMIPProtected + case -38: + return ErrMCProtected + case -39: + return ErrMCChallengeRequired default: return ErrUnknown } diff --git a/installation/errors.go b/installation/errors.go index a4bff4e..6aac419 100644 --- a/installation/errors.go +++ b/installation/errors.go @@ -1,24 +1,176 @@ package installation -import ( - "errors" -) - // #cgo pkg-config: libimobiledevice-1.0 // #include // #include import "C" +import ( + "errors" +) var ( + // ErrInvalidArgs . + ErrInvalidArgs = errors.New("invalid args") // ErrUnknown . ErrUnknown = errors.New("unknown") - // TODO: Add the rest of the errors + // ErrNoDevice . + ErrNoDevice = errors.New("no device") + // ErrNotEnoughData . + ErrNotEnoughData = errors.New("not enough data") + // ErrBadHeader . + ErrBadHeader = errors.New("bad header") + // ErrSslError . + ErrSslError = errors.New("ssl error") + // ErrReceiveTimeout . + ErrReceiveTimeout = errors.New("receive timeout") + // ErrMuxError . + ErrMuxError = errors.New("mux error") + // ErrNoRunningSession . + ErrNoRunningSession = errors.New("no running session") + // ErrInvalidResponse . + ErrInvalidResponse = errors.New("invalid response") + // ErrMissingKey . + ErrMissingKey = errors.New("missing key") + // ErrMissingValue . + ErrMissingValue = errors.New("missing value") + // ErrGetProhibited . + ErrGetProhibited = errors.New("get prohibited") + // ErrSetProhibited . + ErrSetProhibited = errors.New("set prohibited") + // ErrRemoveProhibited . + ErrRemoveProhibited = errors.New("remove prohibited") + // ErrImmutableValue . + ErrImmutableValue = errors.New("immutable value") + // ErrPasswordProtected . + ErrPasswordProtected = errors.New("password protected") + // ErrUserDeniedPairing . + ErrUserDeniedPairing = errors.New("user denied pairing") + // ErrPairingDialogResponsePending . + ErrPairingDialogResponsePending = errors.New("pairing dialog response pending") + // ErrMissingHostID . + ErrMissingHostID = errors.New("missing host id") + // ErrInvalidHostID . + ErrInvalidHostID = errors.New("invalid host id") + // ErrSessionActive . + ErrSessionActive = errors.New("session active") + // ErrSessionInactive . + ErrSessionInactive = errors.New("session inactive") + // ErrMissingSessionID . + ErrMissingSessionID = errors.New("missing session id") + // ErrInvalidSessionID . + ErrInvalidSessionID = errors.New("invalid session id") + // ErrMissingService . + ErrMissingService = errors.New("missing service") + // ErrInvalidService . + ErrInvalidService = errors.New("invalid service") + // ErrServiceLimit . + ErrServiceLimit = errors.New("service limit") + // ErrMissingPairRecord . + ErrMissingPairRecord = errors.New("missing pair record") + // ErrSavePairRecordFailed . + ErrSavePairRecordFailed = errors.New("save pair record failed") + // ErrInvalidPairRecord . + ErrInvalidPairRecord = errors.New("invalid pair record") + // ErrInvalidActivationPeriod . + ErrInvalidActivationPeriod = errors.New("invalid activation period") + // ErrMissingActivationPeriod . + ErrMissingActivationPeriod = errors.New("missing activation period") + // ErrServiceProhibited . + ErrServiceProhibited = errors.New("service prohibited") + // ErrEscrowLocked . + ErrEscrowLocked = errors.New("escrow locked") + // ErrPairingProhibitedOverThisConnection . + ErrPairingProhibitedOverThisConnection = errors.New("pairing prohibited over this connection") + // ErrFMIPProtected . + ErrFMIPProtected = errors.New("FMIP protected") + // ErrMCProtected . + ErrMCProtected = errors.New("MC Protected") + // ErrMCChallengeRequired . + ErrMCChallengeRequired = errors.New("mc challenge required") ) func resultToError(result C.instproxy_error_t) error { switch result { case 0: return nil + case -1: + return ErrInvalidArgs + case -2: + return ErrUnknown + case -3: + return ErrNoDevice + case -4: + return ErrNotEnoughData + case -5: + return ErrBadHeader + case -6: + return ErrSslError + case -7: + return ErrReceiveTimeout + case -8: + return ErrMuxError + case -9: + return ErrNoRunningSession + case -10: + return ErrInvalidResponse + case -11: + return ErrMissingKey + case -12: + return ErrMissingValue + case -13: + return ErrGetProhibited + case -14: + return ErrSetProhibited + case -15: + return ErrRemoveProhibited + case -16: + return ErrImmutableValue + case -17: + return ErrPasswordProtected + case -18: + return ErrUserDeniedPairing + case -19: + return ErrPairingDialogResponsePending + case -20: + return ErrMissingHostID + case -21: + return ErrInvalidHostID + case -22: + return ErrSessionActive + case -23: + return ErrSessionInactive + case -24: + return ErrMissingSessionID + case -25: + return ErrInvalidSessionID + case -26: + return ErrMissingService + case -27: + return ErrInvalidService + case -28: + return ErrServiceLimit + case -29: + return ErrMissingPairRecord + case -30: + return ErrSavePairRecordFailed + case -31: + return ErrInvalidPairRecord + case -32: + return ErrInvalidActivationPeriod + case -33: + return ErrMissingActivationPeriod + case -34: + return ErrServiceProhibited + case -35: + return ErrEscrowLocked + case -36: + return ErrPairingProhibitedOverThisConnection + case -37: + return ErrFMIPProtected + case -38: + return ErrMCProtected + case -39: + return ErrMCChallengeRequired default: return ErrUnknown } diff --git a/lockdown/errors.go b/lockdown/errors.go index 4d5d1fc..4c2b940 100644 --- a/lockdown/errors.go +++ b/lockdown/errors.go @@ -1,23 +1,175 @@ package lockdown -import ( - "errors" -) - // #cgo pkg-config: libimobiledevice-1.0 // #include import "C" +import ( + "errors" +) var ( + // ErrInvalidArgs . + ErrInvalidArgs = errors.New("invalid args") // ErrUnknown . ErrUnknown = errors.New("unknown") - // TODO: Add all the other error types + // ErrNoDevice . + ErrNoDevice = errors.New("no device") + // ErrNotEnoughData . + ErrNotEnoughData = errors.New("not enough data") + // ErrBadHeader . + ErrBadHeader = errors.New("bad header") + // ErrSslError . + ErrSslError = errors.New("ssl error") + // ErrReceiveTimeout . + ErrReceiveTimeout = errors.New("receive timeout") + // ErrMuxError . + ErrMuxError = errors.New("mux error") + // ErrNoRunningSession . + ErrNoRunningSession = errors.New("no running session") + // ErrInvalidResponse . + ErrInvalidResponse = errors.New("invalid response") + // ErrMissingKey . + ErrMissingKey = errors.New("missing key") + // ErrMissingValue . + ErrMissingValue = errors.New("missing value") + // ErrGetProhibited . + ErrGetProhibited = errors.New("get prohibited") + // ErrSetProhibited . + ErrSetProhibited = errors.New("set prohibited") + // ErrRemoveProhibited . + ErrRemoveProhibited = errors.New("remove prohibited") + // ErrImmutableValue . + ErrImmutableValue = errors.New("immutable value") + // ErrPasswordProtected . + ErrPasswordProtected = errors.New("password protected") + // ErrUserDeniedPairing . + ErrUserDeniedPairing = errors.New("user denied pairing") + // ErrPairingDialogResponsePending . + ErrPairingDialogResponsePending = errors.New("pairing dialog response pending") + // ErrMissingHostID . + ErrMissingHostID = errors.New("missing host id") + // ErrInvalidHostID . + ErrInvalidHostID = errors.New("invalid host id") + // ErrSessionActive . + ErrSessionActive = errors.New("session active") + // ErrSessionInactive . + ErrSessionInactive = errors.New("session inactive") + // ErrMissingSessionID . + ErrMissingSessionID = errors.New("missing session id") + // ErrInvalidSessionID . + ErrInvalidSessionID = errors.New("invalid session id") + // ErrMissingService . + ErrMissingService = errors.New("missing service") + // ErrInvalidService . + ErrInvalidService = errors.New("invalid service") + // ErrServiceLimit . + ErrServiceLimit = errors.New("service limit") + // ErrMissingPairRecord . + ErrMissingPairRecord = errors.New("missing pair record") + // ErrSavePairRecordFailed . + ErrSavePairRecordFailed = errors.New("save pair record failed") + // ErrInvalidPairRecord . + ErrInvalidPairRecord = errors.New("invalid pair record") + // ErrInvalidActivationPeriod . + ErrInvalidActivationPeriod = errors.New("invalid activation period") + // ErrMissingActivationPeriod . + ErrMissingActivationPeriod = errors.New("missing activation period") + // ErrServiceProhibited . + ErrServiceProhibited = errors.New("service prohibited") + // ErrEscrowLocked . + ErrEscrowLocked = errors.New("escrow locked") + // ErrPairingProhibitedOverThisConnection . + ErrPairingProhibitedOverThisConnection = errors.New("pairing prohibited over this connection") + // ErrFMIPProtected . + ErrFMIPProtected = errors.New("FMIP protected") + // ErrMCProtected . + ErrMCProtected = errors.New("MC Protected") + // ErrMCChallengeRequired . + ErrMCChallengeRequired = errors.New("mc challenge required") ) func resultToError(result C.lockdownd_error_t) error { switch result { case 0: return nil + case -1: + return ErrInvalidArgs + case -2: + return ErrUnknown + case -3: + return ErrNoDevice + case -4: + return ErrNotEnoughData + case -5: + return ErrBadHeader + case -6: + return ErrSslError + case -7: + return ErrReceiveTimeout + case -8: + return ErrMuxError + case -9: + return ErrNoRunningSession + case -10: + return ErrInvalidResponse + case -11: + return ErrMissingKey + case -12: + return ErrMissingValue + case -13: + return ErrGetProhibited + case -14: + return ErrSetProhibited + case -15: + return ErrRemoveProhibited + case -16: + return ErrImmutableValue + case -17: + return ErrPasswordProtected + case -18: + return ErrUserDeniedPairing + case -19: + return ErrPairingDialogResponsePending + case -20: + return ErrMissingHostID + case -21: + return ErrInvalidHostID + case -22: + return ErrSessionActive + case -23: + return ErrSessionInactive + case -24: + return ErrMissingSessionID + case -25: + return ErrInvalidSessionID + case -26: + return ErrMissingService + case -27: + return ErrInvalidService + case -28: + return ErrServiceLimit + case -29: + return ErrMissingPairRecord + case -30: + return ErrSavePairRecordFailed + case -31: + return ErrInvalidPairRecord + case -32: + return ErrInvalidActivationPeriod + case -33: + return ErrMissingActivationPeriod + case -34: + return ErrServiceProhibited + case -35: + return ErrEscrowLocked + case -36: + return ErrPairingProhibitedOverThisConnection + case -37: + return ErrFMIPProtected + case -38: + return ErrMCProtected + case -39: + return ErrMCChallengeRequired default: return ErrUnknown } diff --git a/lockdown/lockdown.go b/lockdown/lockdown.go index 404c2ae..1061c92 100644 --- a/lockdown/lockdown.go +++ b/lockdown/lockdown.go @@ -4,18 +4,20 @@ package lockdown // #include // #include import "C" - import ( "unsafe" "github.com/pauldotknopf/goidevice/idevice" + "github.com/pauldotknopf/goidevice/plist" ) // Client is a lockdown client type Client interface { Type() (string, error) Pair() error + ValidatePair() error DeviceName() (string, error) + GetPList(string, string) (plist.PList, error) Close() error } @@ -64,6 +66,10 @@ func (s *client) Pair() error { return resultToError(C.lockdownd_pair(s.p, nil)) } +func (s *client) ValidatePair() error { + return resultToError(C.lockdownd_validate_pair(s.p, nil)) +} + func (s *client) DeviceName() (string, error) { var p *C.char err := resultToError(C.lockdownd_get_device_name(s.p, &p)) @@ -75,6 +81,29 @@ func (s *client) DeviceName() (string, error) { return result, err } +func (s *client) GetPList(domain, key string) (plist.PList, error) { + var node C.plist_t + + domainC := C.CString(domain) + keyC := C.CString(key) + defer C.free(unsafe.Pointer(domainC)) + defer C.free(unsafe.Pointer(keyC)) + + if domain == "" { + domainC = nil + } + if key == "" { + keyC = nil + } + + err := resultToError(C.lockdownd_get_value(s.p, domainC, keyC, &node)) + if err != nil { + return nil, err + } + + return plist.FromPointer(unsafe.Pointer(node)), nil +} + func (s *client) Close() error { err := resultToError(C.lockdownd_client_free(s.p)) if err == nil { diff --git a/vendor/github.com/mattn/go-pointer/LICENSE b/vendor/github.com/mattn/go-pointer/LICENSE new file mode 100644 index 0000000..5794edd --- /dev/null +++ b/vendor/github.com/mattn/go-pointer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mattn/go-pointer/pointer.go b/vendor/github.com/mattn/go-pointer/pointer.go index 6cdfae2..08a9853 100644 --- a/vendor/github.com/mattn/go-pointer/pointer.go +++ b/vendor/github.com/mattn/go-pointer/pointer.go @@ -8,7 +8,7 @@ import ( ) var ( - mutex sync.Mutex + mutex sync.RWMutex store = map[unsafe.Pointer]interface{}{} ) @@ -38,9 +38,9 @@ func Restore(ptr unsafe.Pointer) (v interface{}) { return nil } - mutex.Lock() + mutex.RLock() v = store[ptr] - mutex.Unlock() + mutex.RUnlock() return } diff --git a/vendor/github.com/olebedev/emitter/.codeclimate.yml b/vendor/github.com/olebedev/emitter/.codeclimate.yml new file mode 100644 index 0000000..b2bf050 --- /dev/null +++ b/vendor/github.com/olebedev/emitter/.codeclimate.yml @@ -0,0 +1,12 @@ +engines: + fixme: + enabled: true + golint: + enabled: true + gofmt: + enabled: true + govet: + enabled: true +ratings: + paths: + - "*.go" diff --git a/vendor/github.com/olebedev/emitter/.gitignore b/vendor/github.com/olebedev/emitter/.gitignore new file mode 100644 index 0000000..f207625 --- /dev/null +++ b/vendor/github.com/olebedev/emitter/.gitignore @@ -0,0 +1,5 @@ +bin/ +src/ +pkg/ +coverage.html +Makefile diff --git a/vendor/github.com/olebedev/emitter/README.md b/vendor/github.com/olebedev/emitter/README.md index 38542ae..6117661 100644 --- a/vendor/github.com/olebedev/emitter/README.md +++ b/vendor/github.com/olebedev/emitter/README.md @@ -28,7 +28,7 @@ go func(){ for event := range e.On("change") { // do something with event.Args - plintln(event.Int(0)) // cast the first argument to int + println(event.Int(0)) // cast the first argument to int } // listener channel was closed ``` diff --git a/vendor/github.com/olebedev/emitter/wercker.yml b/vendor/github.com/olebedev/emitter/wercker.yml new file mode 100644 index 0000000..c369c48 --- /dev/null +++ b/vendor/github.com/olebedev/emitter/wercker.yml @@ -0,0 +1,18 @@ +box: golang +build: + steps: + - setup-go-workspace + - wercker/golint + - script: + name: go get + code: | + cd $WERCKER_SOURCE_DIR + go version + go get golang.org/x/tools/cmd/cover + go get github.com/mattn/goveralls + - script: + name: go test + code: | + go test . -v -race + go test . -v -covermode=count -coverprofile=profile.cov + goveralls -coverprofile=profile.cov -service=wercker -repotoken=$COVERALLS_TOKEN diff --git a/vendor/modules.txt b/vendor/modules.txt new file mode 100644 index 0000000..d088f0f --- /dev/null +++ b/vendor/modules.txt @@ -0,0 +1,6 @@ +# github.com/mattn/go-pointer v0.0.1 +## explicit +github.com/mattn/go-pointer +# github.com/olebedev/emitter v0.0.0-20190110104742-e8d1457e6aee +## explicit +github.com/olebedev/emitter