Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
briar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Julian Dehm
briar
Commits
57d4d654
Unverified
Commit
57d4d654
authored
8 years ago
by
akwizgran
Browse files
Options
Downloads
Patches
Plain Diff
When checking for overlay apps, ignore Play Services.
parent
9755cd9a
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java
+81
-31
81 additions, 31 deletions
...g/briarproject/briar/android/ScreenFilterMonitorImpl.java
with
81 additions
and
31 deletions
briar-android/src/main/java/org/briarproject/briar/android/ScreenFilterMonitorImpl.java
+
81
−
31
View file @
57d4d654
...
...
@@ -6,10 +6,10 @@ import android.content.Context;
import
android.content.Intent
;
import
android.content.IntentFilter
;
import
android.content.SharedPreferences
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.PackageInfo
;
import
android.content.pm.PackageManager
;
import
android.support.annotation.NonNull
;
import
android.content.pm.PackageManager.NameNotFoundException
;
import
android.content.pm.Signature
;
import
android.support.annotation.Nullable
;
import
android.support.annotation.UiThread
;
import
android.support.v7.preference.PreferenceManager
;
...
...
@@ -19,11 +19,16 @@ import org.briarproject.bramble.api.lifecycle.ServiceException;
import
org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault
;
import
org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault
;
import
org.briarproject.bramble.api.system.AndroidExecutor
;
import
org.briarproject.bramble.util.StringUtils
;
import
org.briarproject.briar.api.android.ScreenFilterMonitor
;
import
java.io.ByteArrayInputStream
;
import
java.io.InputStream
;
import
java.security.cert.CertificateException
;
import
java.security.cert.CertificateFactory
;
import
java.security.cert.X509Certificate
;
import
java.util.Collection
;
import
java.util.HashSet
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.TreeSet
;
...
...
@@ -31,32 +36,57 @@ import java.util.concurrent.Callable;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
javax.inject.Inject
;
import
static
android
.
Manifest
.
permission
.
SYSTEM_ALERT_WINDOW
;
import
static
android
.
content
.
Intent
.
ACTION_PACKAGE_ADDED
;
import
static
android
.
content
.
Intent
.
EXTRA_REPLACING
;
import
static
android
.
content
.
pm
.
ApplicationInfo
.
FLAG_SYSTEM
;
import
static
android
.
content
.
pm
.
ApplicationInfo
.
FLAG_UPDATED_SYSTEM_APP
;
import
static
android
.
content
.
pm
.
PackageManager
.
GET_PERMISSIONS
;
import
static
android
.
content
.
pm
.
PackageManager
.
GET_SIGNATURES
;
import
static
java
.
util
.
logging
.
Level
.
WARNING
;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public
class
ScreenFilterMonitorImpl
extends
BroadcastReceiver
implements
Service
,
ScreenFilterMonitor
{
implements
Service
,
ScreenFilterMonitor
{
private
static
final
Logger
LOG
=
Logger
.
getLogger
(
ScreenFilterMonitorImpl
.
class
.
getName
());
private
static
final
String
PREF_SCREEN_FILTER_APPS
=
"shownScreenFilterApps"
;
/*
* Ignore Play Services if it uses this package name and public key - it's
* effectively a system app, but not flagged as such on older systems
*/
private
static
final
String
PLAY_SERVICES_PACKAGE
=
"com.google.android.gms"
;
private
static
final
String
PLAY_SERVICES_PUBLIC_KEY
=
"30820120300D06092A864886F70D01010105000382010D0030820108"
+
"0282010100AB562E00D83BA208AE0A966F124E29DA11F2AB56D08F58"
+
"E2CCA91303E9B754D372F640A71B1DCB130967624E4656A7776A9219"
+
"3DB2E5BFB724A91E77188B0E6A47A43B33D9609B77183145CCDF7B2E"
+
"586674C9E1565B1F4C6A5955BFF251A63DABF9C55C27222252E875E4"
+
"F8154A645F897168C0B1BFC612EABF785769BB34AA7984DC7E2EA276"
+
"4CAE8307D8C17154D7EE5F64A51A44A602C249054157DC02CD5F5C0E"
+
"55FBEF8519FBE327F0B1511692C5A06F19D18385F5C4DBC2D6B93F68"
+
"CC2979C70E18AB93866B3BD5DB8999552A0E3B4C99DF58FB918BEDC1"
+
"82BA35E003C1B4B10DD244A8EE24FFFD333872AB5221985EDAB0FC0D"
+
"0B145B6AA192858E79020103"
;
private
final
Context
appContext
;
private
final
AndroidExecutor
androidExecutor
;
private
final
LinkedList
<
String
>
appNames
=
new
LinkedList
<>();
private
final
PackageManager
pm
;
private
final
SharedPreferences
prefs
;
private
final
AtomicBoolean
used
=
new
AtomicBoolean
(
false
);
// The following must only be accessed on the UI thread
private
final
Set
<
String
>
apps
=
new
HashSet
<>();
private
final
Set
<
String
>
shownApps
;
// Used solely for the UiThread
private
boolean
serviceStarted
=
false
;
@Inject
...
...
@@ -75,7 +105,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
@Override
public
Void
call
()
{
IntentFilter
intentFilter
=
new
IntentFilter
();
intentFilter
.
addAction
(
Intent
.
ACTION_PACKAGE_ADDED
);
intentFilter
.
addAction
(
ACTION_PACKAGE_ADDED
);
intentFilter
.
addDataScheme
(
"package"
);
appContext
.
registerReceiver
(
ScreenFilterMonitorImpl
.
this
,
intentFilter
);
...
...
@@ -109,9 +139,8 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
}
private
Set
<
String
>
getShownScreenFilterApps
()
{
// res must not be modified
Set
<
String
>
s
=
prefs
.
getStringSet
(
PREF_SCREEN_FILTER_APPS
,
null
);
// Result must not be modified
Set
<
String
>
s
=
prefs
.
getStringSet
(
PREF_SCREEN_FILTER_APPS
,
null
);
HashSet
<
String
>
result
=
new
HashSet
<>();
if
(
s
!=
null
)
{
result
.
addAll
(
s
);
...
...
@@ -121,7 +150,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
@Override
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
if
(!
intent
.
getBooleanExtra
(
Intent
.
EXTRA_REPLACING
,
false
))
{
if
(!
intent
.
getBooleanExtra
(
EXTRA_REPLACING
,
false
))
{
final
String
packageName
=
intent
.
getData
().
getEncodedSchemeSpecificPart
();
androidExecutor
.
runOnUiThread
(
new
Runnable
()
{
...
...
@@ -155,7 +184,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
@Override
@UiThread
public
void
storeAppsAsShown
(
Collection
<
String
>
s
,
boolean
persistent
)
{
HashSet
<
String
>
buf
=
new
HashSet
(
s
);
HashSet
<
String
>
buf
=
new
HashSet
<>
(
s
);
shownApps
.
addAll
(
buf
);
if
(
persistent
&&
!
s
.
isEmpty
())
{
buf
.
addAll
(
getShownScreenFilterApps
());
...
...
@@ -168,7 +197,7 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
private
Set
<
String
>
getInstalledScreenFilterApps
()
{
HashSet
<
String
>
screenFilterApps
=
new
HashSet
<>();
List
<
PackageInfo
>
packageInfos
=
pm
.
getInstalledPackages
(
PackageManager
.
GET_PERMISSIONS
);
pm
.
getInstalledPackages
(
GET_PERMISSIONS
);
for
(
PackageInfo
packageInfo
:
packageInfos
)
{
if
(
isOverlayApp
(
packageInfo
))
{
String
name
=
pkgToString
(
packageInfo
);
...
...
@@ -180,25 +209,22 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
return
screenFilterApps
;
}
// Checks if
pkg
uses the SYSTEM_ALERT_WINDOW permission and if so
// Checks if
a package
uses the SYSTEM_ALERT_WINDOW permission and if so
// returns the app name.
@Nullable
private
String
isOverlayApp
(
String
pkg
)
{
try
{
PackageInfo
pkgInfo
=
pm
.
getPackageInfo
(
pkg
,
PackageManager
.
GET_PERMISSIONS
);
PackageInfo
pkgInfo
=
pm
.
getPackageInfo
(
pkg
,
GET_PERMISSIONS
);
if
(
isOverlayApp
(
pkgInfo
))
{
return
pkgToString
(
pkgInfo
);
}
}
catch
(
PackageManager
.
NameNotFoundException
ignored
)
{
if
(
LOG
.
isLoggable
(
Level
.
WARNING
))
{
LOG
.
warning
(
"Package name not found: "
+
pkg
);
}
}
catch
(
NameNotFoundException
e
)
{
if
(
LOG
.
isLoggable
(
WARNING
))
LOG
.
log
(
WARNING
,
e
.
toString
(),
e
);
}
return
null
;
}
// Fetch the application name for a given package.
// Fetch
es
the application name for a given package.
@Nullable
private
String
pkgToString
(
PackageInfo
pkgInfo
)
{
CharSequence
seq
=
pm
.
getApplicationLabel
(
pkgInfo
.
applicationInfo
);
...
...
@@ -208,25 +234,49 @@ public class ScreenFilterMonitorImpl extends BroadcastReceiver
return
null
;
}
// Checks if an installed p
kg
is a user app using the permission.
// Checks if an installed p
ackage
is a user app using the permission.
private
boolean
isOverlayApp
(
PackageInfo
packageInfo
)
{
int
mask
=
ApplicationInfo
.
FLAG_SYSTEM
|
ApplicationInfo
.
FLAG_UPDATED_SYSTEM_APP
;
int
mask
=
FLAG_SYSTEM
|
FLAG_UPDATED_SYSTEM_APP
;
// Ignore system apps
if
((
packageInfo
.
applicationInfo
.
flags
&
mask
)
!=
0
)
{
return
false
;
}
//Get Permissions
String
[]
requestedPermissions
=
packageInfo
.
requestedPermissions
;
// Ignore Play Services, it's effectively a system app
if
(
isPlayServices
(
packageInfo
.
packageName
))
{
return
false
;
}
// Get permissions
String
[]
requestedPermissions
=
packageInfo
.
requestedPermissions
;
if
(
requestedPermissions
!=
null
)
{
for
(
String
requestedPermission
:
requestedPermissions
)
{
if
(
requestedPermission
.
equals
(
SYSTEM_ALERT_WINDOW
))
{
if
(
requestedPermission
.
equals
(
SYSTEM_ALERT_WINDOW
))
{
return
true
;
}
}
}
return
false
;
}
private
boolean
isPlayServices
(
String
pkg
)
{
if
(!
PLAY_SERVICES_PACKAGE
.
equals
(
pkg
))
return
false
;
try
{
PackageInfo
sigs
=
pm
.
getPackageInfo
(
pkg
,
GET_SIGNATURES
);
// The genuine Play Services app should have a single signature
Signature
[]
signatures
=
sigs
.
signatures
;
if
(
signatures
==
null
||
signatures
.
length
!=
1
)
return
false
;
// Extract the public key from the signature
CertificateFactory
certFactory
=
CertificateFactory
.
getInstance
(
"X509"
);
byte
[]
signatureBytes
=
signatures
[
0
].
toByteArray
();
InputStream
in
=
new
ByteArrayInputStream
(
signatureBytes
);
X509Certificate
cert
=
(
X509Certificate
)
certFactory
.
generateCertificate
(
in
);
byte
[]
publicKeyBytes
=
cert
.
getPublicKey
().
getEncoded
();
String
publicKey
=
StringUtils
.
toHexString
(
publicKeyBytes
);
return
PLAY_SERVICES_PUBLIC_KEY
.
equals
(
publicKey
);
}
catch
(
NameNotFoundException
|
CertificateException
e
)
{
if
(
LOG
.
isLoggable
(
WARNING
))
LOG
.
log
(
WARNING
,
e
.
toString
(),
e
);
return
false
;
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment