Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
2ef71466
Commit
2ef71466
authored
Jan 11, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add fingerprint authentication
parent
1b27e69e
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
192 additions
and
24 deletions
+192
-24
AndroidManifest.xml
src/main/AndroidManifest.xml
+1
-0
MagiskManager.java
src/main/java/com/topjohnwu/magisk/MagiskManager.java
+1
-9
SettingsActivity.java
src/main/java/com/topjohnwu/magisk/SettingsActivity.java
+8
-1
CheckUpdates.java
src/main/java/com/topjohnwu/magisk/asyncs/CheckUpdates.java
+2
-2
PackageReceiver.java
.../java/com/topjohnwu/magisk/receivers/PackageReceiver.java
+2
-1
RequestActivity.java
.../java/com/topjohnwu/magisk/superuser/RequestActivity.java
+60
-6
Const.java
src/main/java/com/topjohnwu/magisk/utils/Const.java
+3
-0
FingerprintHelper.java
...in/java/com/topjohnwu/magisk/utils/FingerprintHelper.java
+84
-0
ic_fingerprint.xml
src/main/res/drawable/ic_fingerprint.xml
+9
-0
activity_request.xml
src/main/res/layout/activity_request.xml
+14
-5
strings.xml
src/main/res/values/strings.xml
+3
-0
app_settings.xml
src/main/res/xml/app_settings.xml
+5
-0
No files found.
src/main/AndroidManifest.xml
View file @
2ef71466
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
<uses-permission
android:name=
"android.permission.RECEIVE_BOOT_COMPLETED"
/>
<uses-permission
android:name=
"android.permission.RECEIVE_BOOT_COMPLETED"
/>
<uses-permission
android:name=
"android.permission.VIBRATE"
/>
<uses-permission
android:name=
"android.permission.VIBRATE"
/>
<uses-permission
android:name=
"android.permission.REQUEST_INSTALL_PACKAGES"
/>
<uses-permission
android:name=
"android.permission.REQUEST_INSTALL_PACKAGES"
/>
<uses-permission
android:name=
"android.permission.USE_FINGERPRINT"
/>
<application
<application
android:name=
".MagiskManager"
android:name=
".MagiskManager"
...
...
src/main/java/com/topjohnwu/magisk/MagiskManager.java
View file @
2ef71466
...
@@ -62,8 +62,6 @@ public class MagiskManager extends Application {
...
@@ -62,8 +62,6 @@ public class MagiskManager extends Application {
public
boolean
magiskHide
;
public
boolean
magiskHide
;
public
boolean
isDarkTheme
;
public
boolean
isDarkTheme
;
public
boolean
updateNotification
;
public
boolean
suReauth
;
public
int
suRequestTimeout
;
public
int
suRequestTimeout
;
public
int
suLogTimeout
=
14
;
public
int
suLogTimeout
=
14
;
public
int
suAccessState
;
public
int
suAccessState
;
...
@@ -74,7 +72,6 @@ public class MagiskManager extends Application {
...
@@ -74,7 +72,6 @@ public class MagiskManager extends Application {
public
String
localeConfig
;
public
String
localeConfig
;
public
int
updateChannel
;
public
int
updateChannel
;
public
String
bootFormat
;
public
String
bootFormat
;
public
String
customChannelUrl
;
public
int
repoOrder
;
public
int
repoOrder
;
// Global resources
// Global resources
...
@@ -135,17 +132,14 @@ public class MagiskManager extends Application {
...
@@ -135,17 +132,14 @@ public class MagiskManager extends Application {
suRequestTimeout
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
SU_REQUEST_TIMEOUT
,
Const
.
Value
.
timeoutList
[
2
]);
suRequestTimeout
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
SU_REQUEST_TIMEOUT
,
Const
.
Value
.
timeoutList
[
2
]);
suResponseType
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
SU_AUTO_RESPONSE
,
Const
.
Value
.
SU_PROMPT
);
suResponseType
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
SU_AUTO_RESPONSE
,
Const
.
Value
.
SU_PROMPT
);
suNotificationType
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
SU_NOTIFICATION
,
Const
.
Value
.
NOTIFICATION_TOAST
);
suNotificationType
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
SU_NOTIFICATION
,
Const
.
Value
.
NOTIFICATION_TOAST
);
suReauth
=
prefs
.
getBoolean
(
Const
.
Key
.
SU_REAUTH
,
false
);
suAccessState
=
suDB
.
getSettings
(
Const
.
Key
.
ROOT_ACCESS
,
Const
.
Value
.
ROOT_ACCESS_APPS_AND_ADB
);
suAccessState
=
suDB
.
getSettings
(
Const
.
Key
.
ROOT_ACCESS
,
Const
.
Value
.
ROOT_ACCESS_APPS_AND_ADB
);
multiuserMode
=
suDB
.
getSettings
(
Const
.
Key
.
SU_MULTIUSER_MODE
,
Const
.
Value
.
MULTIUSER_MODE_OWNER_ONLY
);
multiuserMode
=
suDB
.
getSettings
(
Const
.
Key
.
SU_MULTIUSER_MODE
,
Const
.
Value
.
MULTIUSER_MODE_OWNER_ONLY
);
suNamespaceMode
=
suDB
.
getSettings
(
Const
.
Key
.
SU_MNT_NS
,
Const
.
Value
.
NAMESPACE_MODE_REQUESTER
);
suNamespaceMode
=
suDB
.
getSettings
(
Const
.
Key
.
SU_MNT_NS
,
Const
.
Value
.
NAMESPACE_MODE_REQUESTER
);
// config
// config
isDarkTheme
=
prefs
.
getBoolean
(
Const
.
Key
.
DARK_THEME
,
false
);
isDarkTheme
=
prefs
.
getBoolean
(
Const
.
Key
.
DARK_THEME
,
false
);
updateNotification
=
prefs
.
getBoolean
(
Const
.
Key
.
UPDATE_NOTIFICATION
,
true
);
updateChannel
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
UPDATE_CHANNEL
,
Const
.
Value
.
STABLE_CHANNEL
);
updateChannel
=
Utils
.
getPrefsInt
(
prefs
,
Const
.
Key
.
UPDATE_CHANNEL
,
Const
.
Value
.
STABLE_CHANNEL
);
bootFormat
=
prefs
.
getString
(
Const
.
Key
.
BOOT_FORMAT
,
".img"
);
bootFormat
=
prefs
.
getString
(
Const
.
Key
.
BOOT_FORMAT
,
".img"
);
customChannelUrl
=
prefs
.
getString
(
Const
.
Key
.
CUSTOM_CHANNEL
,
""
);
repoOrder
=
prefs
.
getInt
(
Const
.
Key
.
REPO_ORDER
,
Const
.
Value
.
ORDER_NAME
);
repoOrder
=
prefs
.
getInt
(
Const
.
Key
.
REPO_ORDER
,
Const
.
Value
.
ORDER_NAME
);
}
}
...
@@ -153,10 +147,8 @@ public class MagiskManager extends Application {
...
@@ -153,10 +147,8 @@ public class MagiskManager extends Application {
prefs
.
edit
()
prefs
.
edit
()
.
putBoolean
(
Const
.
Key
.
DARK_THEME
,
isDarkTheme
)
.
putBoolean
(
Const
.
Key
.
DARK_THEME
,
isDarkTheme
)
.
putBoolean
(
Const
.
Key
.
MAGISKHIDE
,
magiskHide
)
.
putBoolean
(
Const
.
Key
.
MAGISKHIDE
,
magiskHide
)
.
putBoolean
(
Const
.
Key
.
UPDATE_NOTIFICATION
,
updateNotification
)
.
putBoolean
(
Const
.
Key
.
HOSTS
,
Utils
.
itemExist
(
Const
.
MAGISK_HOST_FILE
()))
.
putBoolean
(
Const
.
Key
.
HOSTS
,
Utils
.
itemExist
(
Const
.
MAGISK_HOST_FILE
()))
.
putBoolean
(
Const
.
Key
.
COREONLY
,
Utils
.
itemExist
(
Const
.
MAGISK_DISABLE_FILE
))
.
putBoolean
(
Const
.
Key
.
COREONLY
,
Utils
.
itemExist
(
Const
.
MAGISK_DISABLE_FILE
))
.
putBoolean
(
Const
.
Key
.
SU_REAUTH
,
suReauth
)
.
putString
(
Const
.
Key
.
SU_REQUEST_TIMEOUT
,
String
.
valueOf
(
suRequestTimeout
))
.
putString
(
Const
.
Key
.
SU_REQUEST_TIMEOUT
,
String
.
valueOf
(
suRequestTimeout
))
.
putString
(
Const
.
Key
.
SU_AUTO_RESPONSE
,
String
.
valueOf
(
suResponseType
))
.
putString
(
Const
.
Key
.
SU_AUTO_RESPONSE
,
String
.
valueOf
(
suResponseType
))
.
putString
(
Const
.
Key
.
SU_NOTIFICATION
,
String
.
valueOf
(
suNotificationType
))
.
putString
(
Const
.
Key
.
SU_NOTIFICATION
,
String
.
valueOf
(
suNotificationType
))
...
@@ -171,7 +163,7 @@ public class MagiskManager extends Application {
...
@@ -171,7 +163,7 @@ public class MagiskManager extends Application {
.
apply
();
.
apply
();
}
}
public
static
void
toast
(
String
msg
,
int
duration
)
{
public
static
void
toast
(
CharSequence
msg
,
int
duration
)
{
mHandler
.
post
(()
->
Toast
.
makeText
(
weakSelf
.
get
(),
msg
,
duration
).
show
());
mHandler
.
post
(()
->
Toast
.
makeText
(
weakSelf
.
get
(),
msg
,
duration
).
show
());
}
}
...
...
src/main/java/com/topjohnwu/magisk/SettingsActivity.java
View file @
2ef71466
...
@@ -22,6 +22,7 @@ import com.topjohnwu.magisk.asyncs.CheckUpdates;
...
@@ -22,6 +22,7 @@ import com.topjohnwu.magisk.asyncs.CheckUpdates;
import
com.topjohnwu.magisk.asyncs.HideManager
;
import
com.topjohnwu.magisk.asyncs.HideManager
;
import
com.topjohnwu.magisk.components.Activity
;
import
com.topjohnwu.magisk.components.Activity
;
import
com.topjohnwu.magisk.utils.Const
;
import
com.topjohnwu.magisk.utils.Const
;
import
com.topjohnwu.magisk.utils.FingerprintHelper
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Topic
;
import
com.topjohnwu.magisk.utils.Topic
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.Utils
;
...
@@ -112,13 +113,14 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
...
@@ -112,13 +113,14 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
multiuserMode
=
(
ListPreference
)
findPreference
(
Const
.
Key
.
SU_MULTIUSER_MODE
);
multiuserMode
=
(
ListPreference
)
findPreference
(
Const
.
Key
.
SU_MULTIUSER_MODE
);
namespaceMode
=
(
ListPreference
)
findPreference
(
Const
.
Key
.
SU_MNT_NS
);
namespaceMode
=
(
ListPreference
)
findPreference
(
Const
.
Key
.
SU_MNT_NS
);
SwitchPreference
reauth
=
(
SwitchPreference
)
findPreference
(
Const
.
Key
.
SU_REAUTH
);
SwitchPreference
reauth
=
(
SwitchPreference
)
findPreference
(
Const
.
Key
.
SU_REAUTH
);
SwitchPreference
fingerprint
=
(
SwitchPreference
)
findPreference
(
Const
.
Key
.
SU_FINGERPRINT
);
updateChannel
.
setOnPreferenceChangeListener
((
pref
,
o
)
->
{
updateChannel
.
setOnPreferenceChangeListener
((
pref
,
o
)
->
{
mm
.
updateChannel
=
Integer
.
parseInt
((
String
)
o
);
mm
.
updateChannel
=
Integer
.
parseInt
((
String
)
o
);
if
(
mm
.
updateChannel
==
Const
.
Value
.
CUSTOM_CHANNEL
)
{
if
(
mm
.
updateChannel
==
Const
.
Value
.
CUSTOM_CHANNEL
)
{
View
v
=
LayoutInflater
.
from
(
getActivity
()).
inflate
(
R
.
layout
.
custom_channel_dialog
,
null
);
View
v
=
LayoutInflater
.
from
(
getActivity
()).
inflate
(
R
.
layout
.
custom_channel_dialog
,
null
);
EditText
url
=
v
.
findViewById
(
R
.
id
.
custom_url
);
EditText
url
=
v
.
findViewById
(
R
.
id
.
custom_url
);
url
.
setText
(
mm
.
customChannelUrl
);
url
.
setText
(
mm
.
prefs
.
getString
(
Const
.
Key
.
CUSTOM_CHANNEL
,
""
)
);
new
AlertDialog
.
Builder
(
getActivity
())
new
AlertDialog
.
Builder
(
getActivity
())
.
setTitle
(
R
.
string
.
settings_update_custom
)
.
setTitle
(
R
.
string
.
settings_update_custom
)
.
setView
(
v
)
.
setView
(
v
)
...
@@ -144,6 +146,11 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
...
@@ -144,6 +146,11 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
reauth
.
setSummary
(
R
.
string
.
android_o_not_support
);
reauth
.
setSummary
(
R
.
string
.
android_o_not_support
);
}
}
// Remove fingerprint option if not possible
if
(!
FingerprintHelper
.
canUseFingerprint
())
{
suCategory
.
removePreference
(
fingerprint
);
}
if
(
mm
.
getPackageName
().
equals
(
Const
.
ORIG_PKG_NAME
)
&&
mm
.
magiskVersionCode
>=
1440
)
{
if
(
mm
.
getPackageName
().
equals
(
Const
.
ORIG_PKG_NAME
)
&&
mm
.
magiskVersionCode
>=
1440
)
{
hideManager
.
setOnPreferenceClickListener
((
pref
)
->
{
hideManager
.
setOnPreferenceClickListener
((
pref
)
->
{
Utils
.
runWithPermission
(
getActivity
(),
Utils
.
runWithPermission
(
getActivity
(),
...
...
src/main/java/com/topjohnwu/magisk/asyncs/CheckUpdates.java
View file @
2ef71466
...
@@ -33,7 +33,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
...
@@ -33,7 +33,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
jsonStr
=
WebService
.
getString
(
Const
.
Url
.
BETA_URL
);
jsonStr
=
WebService
.
getString
(
Const
.
Url
.
BETA_URL
);
break
;
break
;
case
Const
.
Value
.
CUSTOM_CHANNEL
:
case
Const
.
Value
.
CUSTOM_CHANNEL
:
jsonStr
=
WebService
.
getString
(
mm
.
customChannelUrl
);
jsonStr
=
WebService
.
getString
(
mm
.
prefs
.
getString
(
Const
.
Key
.
CUSTOM_CHANNEL
,
""
)
);
break
;
break
;
}
}
try
{
try
{
...
@@ -54,7 +54,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
...
@@ -54,7 +54,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
@Override
@Override
protected
void
onPostExecute
(
Void
v
)
{
protected
void
onPostExecute
(
Void
v
)
{
MagiskManager
mm
=
MagiskManager
.
get
();
MagiskManager
mm
=
MagiskManager
.
get
();
if
(
showNotification
&&
mm
.
updateNotification
)
{
if
(
showNotification
&&
mm
.
prefs
.
getBoolean
(
Const
.
Key
.
UPDATE_NOTIFICATION
,
true
)
)
{
if
(
BuildConfig
.
VERSION_CODE
<
mm
.
remoteManagerVersionCode
)
{
if
(
BuildConfig
.
VERSION_CODE
<
mm
.
remoteManagerVersionCode
)
{
ShowUI
.
managerUpdateNotification
();
ShowUI
.
managerUpdateNotification
();
}
else
if
(
mm
.
magiskVersionCode
<
mm
.
remoteMagiskVersionCode
)
{
}
else
if
(
mm
.
magiskVersionCode
<
mm
.
remoteMagiskVersionCode
)
{
...
...
src/main/java/com/topjohnwu/magisk/receivers/PackageReceiver.java
View file @
2ef71466
...
@@ -5,6 +5,7 @@ import android.content.Context;
...
@@ -5,6 +5,7 @@ import android.content.Context;
import
android.content.Intent
;
import
android.content.Intent
;
import
com.topjohnwu.magisk.MagiskManager
;
import
com.topjohnwu.magisk.MagiskManager
;
import
com.topjohnwu.magisk.utils.Const
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Shell
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.Utils
;
...
@@ -18,7 +19,7 @@ public class PackageReceiver extends BroadcastReceiver {
...
@@ -18,7 +19,7 @@ public class PackageReceiver extends BroadcastReceiver {
switch
(
intent
.
getAction
())
{
switch
(
intent
.
getAction
())
{
case
Intent
.
ACTION_PACKAGE_REPLACED
:
case
Intent
.
ACTION_PACKAGE_REPLACED
:
// This will only work pre-O
// This will only work pre-O
if
(
mm
.
suReauth
)
{
if
(
mm
.
prefs
.
getBoolean
(
Const
.
Key
.
SU_REAUTH
,
false
)
)
{
mm
.
suDB
.
deletePolicy
(
pkg
);
mm
.
suDB
.
deletePolicy
(
pkg
);
}
}
break
;
break
;
...
...
src/main/java/com/topjohnwu/magisk/superuser/RequestActivity.java
View file @
2ef71466
...
@@ -3,12 +3,14 @@ package com.topjohnwu.magisk.superuser;
...
@@ -3,12 +3,14 @@ package com.topjohnwu.magisk.superuser;
import
android.content.ContentValues
;
import
android.content.ContentValues
;
import
android.content.Intent
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.content.pm.PackageManager
;
import
android.hardware.fingerprint.FingerprintManager
;
import
android.net.LocalSocket
;
import
android.net.LocalSocket
;
import
android.net.LocalSocketAddress
;
import
android.net.LocalSocketAddress
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.os.CountDownTimer
;
import
android.os.CountDownTimer
;
import
android.os.FileObserver
;
import
android.os.FileObserver
;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
android.view.View
;
import
android.view.Window
;
import
android.view.Window
;
import
android.widget.ArrayAdapter
;
import
android.widget.ArrayAdapter
;
import
android.widget.Button
;
import
android.widget.Button
;
...
@@ -23,6 +25,7 @@ import com.topjohnwu.magisk.asyncs.ParallelTask;
...
@@ -23,6 +25,7 @@ import com.topjohnwu.magisk.asyncs.ParallelTask;
import
com.topjohnwu.magisk.components.Activity
;
import
com.topjohnwu.magisk.components.Activity
;
import
com.topjohnwu.magisk.container.Policy
;
import
com.topjohnwu.magisk.container.Policy
;
import
com.topjohnwu.magisk.utils.Const
;
import
com.topjohnwu.magisk.utils.Const
;
import
com.topjohnwu.magisk.utils.FingerprintHelper
;
import
com.topjohnwu.magisk.utils.Utils
;
import
com.topjohnwu.magisk.utils.Utils
;
import
java.io.DataInputStream
;
import
java.io.DataInputStream
;
...
@@ -40,6 +43,8 @@ public class RequestActivity extends Activity {
...
@@ -40,6 +43,8 @@ public class RequestActivity extends Activity {
@BindView
(
R
.
id
.
package_name
)
TextView
packageNameView
;
@BindView
(
R
.
id
.
package_name
)
TextView
packageNameView
;
@BindView
(
R
.
id
.
grant_btn
)
Button
grant_btn
;
@BindView
(
R
.
id
.
grant_btn
)
Button
grant_btn
;
@BindView
(
R
.
id
.
deny_btn
)
Button
deny_btn
;
@BindView
(
R
.
id
.
deny_btn
)
Button
deny_btn
;
@BindView
(
R
.
id
.
fingerprint
)
ImageView
fingerprintImg
;
@BindView
(
R
.
id
.
warning
)
TextView
warning
;
private
String
socketPath
;
private
String
socketPath
;
private
LocalSocket
socket
;
private
LocalSocket
socket
;
...
@@ -49,6 +54,7 @@ public class RequestActivity extends Activity {
...
@@ -49,6 +54,7 @@ public class RequestActivity extends Activity {
private
boolean
hasTimeout
;
private
boolean
hasTimeout
;
private
Policy
policy
;
private
Policy
policy
;
private
CountDownTimer
timer
;
private
CountDownTimer
timer
;
private
FingerprintHelper
fingerprintHelper
;
@Override
@Override
public
int
getDarkTheme
()
{
public
int
getDarkTheme
()
{
...
@@ -80,6 +86,15 @@ public class RequestActivity extends Activity {
...
@@ -80,6 +86,15 @@ public class RequestActivity extends Activity {
new
SocketManager
(
this
).
exec
();
new
SocketManager
(
this
).
exec
();
}
}
@Override
public
void
finish
()
{
if
(
timer
!=
null
)
timer
.
cancel
();
if
(
fingerprintHelper
!=
null
)
fingerprintHelper
.
cancel
();
super
.
finish
();
}
private
boolean
cancelTimeout
()
{
private
boolean
cancelTimeout
()
{
timer
.
cancel
();
timer
.
cancel
();
deny_btn
.
setText
(
getString
(
R
.
string
.
deny
));
deny_btn
.
setText
(
getString
(
R
.
string
.
deny
));
...
@@ -128,11 +143,49 @@ public class RequestActivity extends Activity {
...
@@ -128,11 +143,49 @@ public class RequestActivity extends Activity {
}
}
};
};
grant_btn
.
setOnClickListener
(
v
->
{
boolean
useFingerprint
=
mm
.
prefs
.
getBoolean
(
Const
.
Key
.
SU_FINGERPRINT
,
false
)
&&
FingerprintHelper
.
canUseFingerprint
();
handleAction
(
Policy
.
ALLOW
);
timer
.
cancel
();
if
(
useFingerprint
)
{
});
try
{
grant_btn
.
requestFocus
();
fingerprintHelper
=
new
FingerprintHelper
()
{
@Override
public
void
onAuthenticationError
(
int
errorCode
,
CharSequence
errString
)
{
warning
.
setText
(
errString
);
}
@Override
public
void
onAuthenticationHelp
(
int
helpCode
,
CharSequence
helpString
)
{
warning
.
setText
(
helpString
);
}
@Override
public
void
onAuthenticationSucceeded
(
FingerprintManager
.
AuthenticationResult
result
)
{
handleAction
(
Policy
.
ALLOW
);
}
@Override
public
void
onAuthenticationFailed
()
{
warning
.
setText
(
R
.
string
.
auth_fail
);
}
};
fingerprintHelper
.
startAuth
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
useFingerprint
=
false
;
}
}
if
(!
useFingerprint
)
{
grant_btn
.
setOnClickListener
(
v
->
{
handleAction
(
Policy
.
ALLOW
);
timer
.
cancel
();
});
grant_btn
.
requestFocus
();
}
grant_btn
.
setVisibility
(
useFingerprint
?
View
.
GONE
:
View
.
VISIBLE
);
fingerprintImg
.
setVisibility
(
useFingerprint
?
View
.
VISIBLE
:
View
.
GONE
);
deny_btn
.
setOnClickListener
(
v
->
{
deny_btn
.
setOnClickListener
(
v
->
{
handleAction
(
Policy
.
DENY
);
handleAction
(
Policy
.
DENY
);
timer
.
cancel
();
timer
.
cancel
();
...
@@ -151,8 +204,9 @@ public class RequestActivity extends Activity {
...
@@ -151,8 +204,9 @@ public class RequestActivity extends Activity {
public
void
onBackPressed
()
{
public
void
onBackPressed
()
{
if
(
policy
!=
null
)
{
if
(
policy
!=
null
)
{
handleAction
(
Policy
.
DENY
);
handleAction
(
Policy
.
DENY
);
}
else
{
finish
();
}
}
finish
();
}
}
void
handleAction
()
{
void
handleAction
()
{
...
...
src/main/java/com/topjohnwu/magisk/utils/Const.java
View file @
2ef71466
...
@@ -23,6 +23,8 @@ public class Const {
...
@@ -23,6 +23,8 @@ public class Const {
public
static
final
String
UTIL_FUNCTIONS
=
"util_functions.sh"
;
public
static
final
String
UTIL_FUNCTIONS
=
"util_functions.sh"
;
public
static
final
String
ANDROID_MANIFEST
=
"AndroidManifest.xml"
;
public
static
final
String
ANDROID_MANIFEST
=
"AndroidManifest.xml"
;
public
static
final
String
SU_KEYSTORE_KEY
=
"su_key"
;
// Paths
// Paths
public
static
final
String
MAGISK_DISABLE_FILE
=
"/cache/.disable_magisk"
;
public
static
final
String
MAGISK_DISABLE_FILE
=
"/cache/.disable_magisk"
;
public
static
final
String
TMP_FOLDER_PATH
=
"/dev/tmp"
;
public
static
final
String
TMP_FOLDER_PATH
=
"/dev/tmp"
;
...
@@ -109,6 +111,7 @@ public class Const {
...
@@ -109,6 +111,7 @@ public class Const {
public
static
final
String
SU_AUTO_RESPONSE
=
"su_auto_response"
;
public
static
final
String
SU_AUTO_RESPONSE
=
"su_auto_response"
;
public
static
final
String
SU_NOTIFICATION
=
"su_notification"
;
public
static
final
String
SU_NOTIFICATION
=
"su_notification"
;
public
static
final
String
SU_REAUTH
=
"su_reauth"
;
public
static
final
String
SU_REAUTH
=
"su_reauth"
;
public
static
final
String
SU_FINGERPRINT
=
"su_fingerprint"
;
// intents
// intents
public
static
final
String
OPEN_SECTION
=
"section"
;
public
static
final
String
OPEN_SECTION
=
"section"
;
...
...
src/main/java/com/topjohnwu/magisk/utils/FingerprintHelper.java
0 → 100644
View file @
2ef71466
package
com
.
topjohnwu
.
magisk
.
utils
;
import
android.annotation.TargetApi
;
import
android.app.KeyguardManager
;
import
android.hardware.fingerprint.FingerprintManager
;
import
android.os.Build
;
import
android.os.CancellationSignal
;
import
android.security.keystore.KeyGenParameterSpec
;
import
android.security.keystore.KeyPermanentlyInvalidatedException
;
import
android.security.keystore.KeyProperties
;
import
com.topjohnwu.magisk.MagiskManager
;
import
java.security.KeyStore
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.SecretKey
;
@TargetApi
(
Build
.
VERSION_CODES
.
M
)
public
abstract
class
FingerprintHelper
extends
FingerprintManager
.
AuthenticationCallback
{
private
FingerprintManager
manager
;
private
Cipher
cipher
;
private
CancellationSignal
cancel
;
public
static
boolean
canUseFingerprint
()
{
if
(
Build
.
VERSION
.
SDK_INT
<
Build
.
VERSION_CODES
.
M
)
return
false
;
MagiskManager
mm
=
MagiskManager
.
get
();
KeyguardManager
km
=
mm
.
getSystemService
(
KeyguardManager
.
class
);
FingerprintManager
fm
=
mm
.
getSystemService
(
FingerprintManager
.
class
);
return
km
.
isKeyguardSecure
()
&&
fm
.
isHardwareDetected
()
&&
fm
.
hasEnrolledFingerprints
();
}
protected
FingerprintHelper
()
throws
Exception
{
MagiskManager
mm
=
MagiskManager
.
get
();
KeyStore
keyStore
=
KeyStore
.
getInstance
(
"AndroidKeyStore"
);
manager
=
mm
.
getSystemService
(
FingerprintManager
.
class
);
cipher
=
Cipher
.
getInstance
(
KeyProperties
.
KEY_ALGORITHM_AES
+
"/"
+
KeyProperties
.
BLOCK_MODE_CBC
+
"/"
+
KeyProperties
.
ENCRYPTION_PADDING_PKCS7
);
keyStore
.
load
(
null
);
SecretKey
key
=
(
SecretKey
)
keyStore
.
getKey
(
Const
.
SU_KEYSTORE_KEY
,
null
);
if
(
key
==
null
)
{
key
=
generateKey
();
}
try
{
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
}
catch
(
KeyPermanentlyInvalidatedException
e
)
{
// Only happens on Marshmallow
key
=
generateKey
();
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
}
}
public
void
startAuth
()
{
cancel
=
new
CancellationSignal
();
FingerprintManager
.
CryptoObject
cryptoObject
=
new
FingerprintManager
.
CryptoObject
(
cipher
);
manager
.
authenticate
(
cryptoObject
,
cancel
,
0
,
this
,
null
);
}
public
void
cancel
()
{
if
(
cancel
!=
null
)
cancel
.
cancel
();
}
private
SecretKey
generateKey
()
throws
Exception
{
KeyGenerator
keygen
=
KeyGenerator
.
getInstance
(
KeyProperties
.
KEY_ALGORITHM_AES
,
"AndroidKeyStore"
);
KeyGenParameterSpec
.
Builder
builder
=
new
KeyGenParameterSpec
.
Builder
(
Const
.
SU_KEYSTORE_KEY
,
KeyProperties
.
PURPOSE_ENCRYPT
|
KeyProperties
.
PURPOSE_DECRYPT
)
.
setBlockModes
(
KeyProperties
.
BLOCK_MODE_CBC
)
.
setUserAuthenticationRequired
(
true
)
.
setEncryptionPaddings
(
KeyProperties
.
ENCRYPTION_PADDING_PKCS7
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
N
)
{
builder
.
setInvalidatedByBiometricEnrollment
(
false
);
}
keygen
.
init
(
builder
.
build
());
return
keygen
.
generateKey
();
}
}
src/main/res/drawable/ic_fingerprint.xml
0 → 100644
View file @
2ef71466
<vector
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:width=
"24dp"
android:height=
"24dp"
android:viewportWidth=
"24.0"
android:viewportHeight=
"24.0"
>
<path
android:fillColor=
"#FF000000"
android:pathData=
"M17.81,4.47c-0.08,0 -0.16,-0.02 -0.23,-0.06C15.66,3.42 14,3 12.01,3c-1.98,0 -3.86,0.47 -5.57,1.41 -0.24,0.13 -0.54,0.04 -0.68,-0.2 -0.13,-0.24 -0.04,-0.55 0.2,-0.68C7.82,2.52 9.86,2 12.01,2c2.13,0 3.99,0.47 6.03,1.52 0.25,0.13 0.34,0.43 0.21,0.67 -0.09,0.18 -0.26,0.28 -0.44,0.28zM3.5,9.72c-0.1,0 -0.2,-0.03 -0.29,-0.09 -0.23,-0.16 -0.28,-0.47 -0.12,-0.7 0.99,-1.4 2.25,-2.5 3.75,-3.27C9.98,4.04 14,4.03 17.15,5.65c1.5,0.77 2.76,1.86 3.75,3.25 0.16,0.22 0.11,0.54 -0.12,0.7 -0.23,0.16 -0.54,0.11 -0.7,-0.12 -0.9,-1.26 -2.04,-2.25 -3.39,-2.94 -2.87,-1.47 -6.54,-1.47 -9.4,0.01 -1.36,0.7 -2.5,1.7 -3.4,2.96 -0.08,0.14 -0.23,0.21 -0.39,0.21zM9.75,21.79c-0.13,0 -0.26,-0.05 -0.35,-0.15 -0.87,-0.87 -1.34,-1.43 -2.01,-2.64 -0.69,-1.23 -1.05,-2.73 -1.05,-4.34 0,-2.97 2.54,-5.39 5.66,-5.39s5.66,2.42 5.66,5.39c0,0.28 -0.22,0.5 -0.5,0.5s-0.5,-0.22 -0.5,-0.5c0,-2.42 -2.09,-4.39 -4.66,-4.39 -2.57,0 -4.66,1.97 -4.66,4.39 0,1.44 0.32,2.77 0.93,3.85 0.64,1.15 1.08,1.64 1.85,2.42 0.19,0.2 0.19,0.51 0,0.71 -0.11,0.1 -0.24,0.15 -0.37,0.15zM16.92,19.94c-1.19,0 -2.24,-0.3 -3.1,-0.89 -1.49,-1.01 -2.38,-2.65 -2.38,-4.39 0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5c0,1.41 0.72,2.74 1.94,3.56 0.71,0.48 1.54,0.71 2.54,0.71 0.24,0 0.64,-0.03 1.04,-0.1 0.27,-0.05 0.53,0.13 0.58,0.41 0.05,0.27 -0.13,0.53 -0.41,0.58 -0.57,0.11 -1.07,0.12 -1.21,0.12zM14.91,22c-0.04,0 -0.09,-0.01 -0.13,-0.02 -1.59,-0.44 -2.63,-1.03 -3.72,-2.1 -1.4,-1.39 -2.17,-3.24 -2.17,-5.22 0,-1.62 1.38,-2.94 3.08,-2.94 1.7,0 3.08,1.32 3.08,2.94 0,1.07 0.93,1.94 2.08,1.94s2.08,-0.87 2.08,-1.94c0,-3.77 -3.25,-6.83 -7.25,-6.83 -2.84,0 -5.44,1.58 -6.61,4.03 -0.39,0.81 -0.59,1.76 -0.59,2.8 0,0.78 0.07,2.01 0.67,3.61 0.1,0.26 -0.03,0.55 -0.29,0.64 -0.26,0.1 -0.55,-0.04 -0.64,-0.29 -0.49,-1.31 -0.73,-2.61 -0.73,-3.96 0,-1.2 0.23,-2.29 0.68,-3.24 1.33,-2.79 4.28,-4.6 7.51,-4.6 4.55,0 8.25,3.51 8.25,7.83 0,1.62 -1.38,2.94 -3.08,2.94s-3.08,-1.32 -3.08,-2.94c0,-1.07 -0.93,-1.94 -2.08,-1.94s-2.08,0.87 -2.08,1.94c0,1.71 0.66,3.31 1.87,4.51 0.95,0.94 1.86,1.46 3.27,1.85 0.27,0.07 0.42,0.35 0.35,0.61 -0.05,0.23 -0.26,0.38 -0.47,0.38z"
/>
</vector>
src/main/res/layout/activity_request.xml
View file @
2ef71466
...
@@ -101,18 +101,27 @@
...
@@ -101,18 +101,27 @@
<Button
<Button
style=
"?android:buttonBarButtonStyle"
style=
"?android:buttonBarButtonStyle"
android:text=
"@string/deny_with_str"
android:text=
"@string/deny_with_str"
android:layout_width=
"
match_parent
"
android:layout_width=
"
0dp
"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:id=
"@+id/deny_btn"
android:id=
"@+id/deny_btn"
android:layout_weight=
"1"
/>
android:layout_weight=
"1"
/>
<Button
<Button
android:id=
"@+id/grant_btn"
style=
"?android:buttonBarButtonStyle"
style=
"?android:buttonBarButtonStyle"
android:text=
"@string/grant"
android:layout_width=
"0dp"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:id=
"@+id/grant_btn"
android:layout_weight=
"1"
android:layout_weight=
"1"
/>
android:text=
"@string/grant"
/>
<ImageView
android:id=
"@+id/fingerprint"
android:layout_width=
"0dp"
android:layout_height=
"match_parent"
android:layout_weight=
"1"
android:padding=
"7dp"
android:tint=
"?attr/colorAccent"
android:src=
"@drawable/ic_fingerprint"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
src/main/res/values/strings.xml
View file @
2ef71466
...
@@ -166,6 +166,8 @@
...
@@ -166,6 +166,8 @@
<string
name=
"request_timeout_summary"
>
%1$s seconds
</string>
<string
name=
"request_timeout_summary"
>
%1$s seconds
</string>
<string
name=
"settings_su_reauth_title"
>
Re-authenticate after upgrade
</string>
<string
name=
"settings_su_reauth_title"
>
Re-authenticate after upgrade
</string>
<string
name=
"settings_su_reauth_summary"
>
Re-authenticate superuser permissions after an application upgrades
</string>
<string
name=
"settings_su_reauth_summary"
>
Re-authenticate superuser permissions after an application upgrades
</string>
<string
name=
"settings_su_fingerprint_title"
>
Enable Fingerprint Authentication
</string>
<string
name=
"settings_su_fingerprint_summary"
>
Use fingerprint scanner to allow superuser requests
</string>
<string
name=
"multiuser_mode"
>
Multiuser Mode
</string>
<string
name=
"multiuser_mode"
>
Multiuser Mode
</string>
<string
name=
"settings_owner_only"
>
Device Owner Only
</string>
<string
name=
"settings_owner_only"
>
Device Owner Only
</string>
...
@@ -212,6 +214,7 @@
...
@@ -212,6 +214,7 @@
<string
name=
"su_revoke_msg"
>
Confirm to revoke %1$s rights?
</string>
<string
name=
"su_revoke_msg"
>
Confirm to revoke %1$s rights?
</string>
<string
name=
"toast"
>
Toast
</string>
<string
name=
"toast"
>
Toast
</string>
<string
name=
"none"
>
None
</string>
<string
name=
"none"
>
None
</string>
<string
name=
"auth_fail"
>
Authentication Failed
</string>
<!--Superuser logs-->
<!--Superuser logs-->
<string
name=
"pid"
>
PID:\u0020
</string>
<string
name=
"pid"
>
PID:\u0020
</string>
...
...
src/main/res/xml/app_settings.xml
View file @
2ef71466
...
@@ -107,6 +107,11 @@
...
@@ -107,6 +107,11 @@
android:entries=
"@array/su_notification"
android:entries=
"@array/su_notification"
android:entryValues=
"@array/value_array"
/>
android:entryValues=
"@array/value_array"
/>
<SwitchPreference
android:key=
"su_fingerprint"
android:title=
"@string/settings_su_fingerprint_title"
android:summary=
"@string/settings_su_fingerprint_summary"
/>
<SwitchPreference
<SwitchPreference
android:key=
"su_reauth"
android:key=
"su_reauth"
android:title=
"@string/settings_su_reauth_title"
android:title=
"@string/settings_su_reauth_title"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment