Skip to content

Commit cb83647

Browse files
committed
Auth: Verify request data before use in AskPermissionActivity
Fixes #1800
1 parent 9673aa2 commit cb83647

File tree

1 file changed

+83
-55
lines changed

1 file changed

+83
-55
lines changed

play-services-core/src/main/java/org/microg/gms/auth/AskPermissionActivity.java

Lines changed: 83 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import android.accounts.AccountManager;
2222
import android.app.NotificationManager;
2323
import android.content.Context;
24+
import android.content.Intent;
2425
import android.content.pm.ApplicationInfo;
2526
import android.content.pm.PackageManager;
2627
import android.graphics.Bitmap;
@@ -58,17 +59,73 @@ public class AskPermissionActivity extends AccountAuthenticatorActivity {
5859
public static final String EXTRA_CONSENT_DATA = "consent_data";
5960

6061
private static final String TAG = "GmsAuthAskPermission";
61-
private Account account;
62-
private String packageName;
63-
private String service;
6462
private AuthManager authManager;
65-
private ConsentData consentData;
66-
private boolean fromAccountManager = false;
63+
private IntentData data;
64+
65+
private static class IntentData {
66+
private String accountName;
67+
private String accountType;
68+
private Account account;
69+
70+
private String packageName;
71+
private String service;
72+
73+
private int callerUid;
74+
private int callerPid;
75+
76+
private ConsentData consentData;
77+
private boolean fromAccountManager = false;
78+
79+
private CharSequence appLabel;
80+
private Drawable appIcon;
81+
82+
private IntentData(Intent intent) {
83+
if (intent != null) {
84+
accountName = intent.getStringExtra(KEY_ACCOUNT_NAME);
85+
accountType = intent.getStringExtra(KEY_ACCOUNT_TYPE);
86+
packageName = intent.getStringExtra(KEY_ANDROID_PACKAGE_NAME);
87+
service = intent.getStringExtra(KEY_AUTHTOKEN);
88+
callerUid = intent.getIntExtra(KEY_CALLER_UID, 0);
89+
callerPid = intent.getIntExtra(KEY_CALLER_PID, 0);
90+
fromAccountManager = intent.hasExtra(EXTRA_FROM_ACCOUNT_MANAGER);
91+
if (intent.hasExtra(EXTRA_CONSENT_DATA)) {
92+
try {
93+
consentData = ConsentData.ADAPTER.decode(intent.getByteArrayExtra(EXTRA_CONSENT_DATA));
94+
} catch (Exception e) {
95+
// Ignore
96+
}
97+
}
98+
}
99+
if (accountName != null && accountType != null) {
100+
account = new Account(accountName, accountType);
101+
}
102+
}
103+
104+
private void verify(Context context) throws Exception {
105+
if (accountName == null || accountType == null || account == null) throw new IllegalArgumentException("Required account information missing");
106+
if (packageName == null || service == null) throw new IllegalArgumentException("Required request information missing");
107+
if (callerUid == 0) throw new IllegalArgumentException("Required caller information missing");
108+
PackageUtils.getAndCheckPackage(context, packageName, callerUid, callerPid);
109+
110+
PackageManager packageManager = context.getPackageManager();
111+
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
112+
appLabel = packageManager.getApplicationLabel(applicationInfo);
113+
appIcon = packageManager.getApplicationIcon(applicationInfo);
114+
}
115+
}
67116

68117
@Override
69118
protected void onCreate(Bundle savedInstanceState) {
70119
super.onCreate(savedInstanceState);
71120
setContentView(R.layout.ask_permission);
121+
data = new IntentData(getIntent());
122+
try {
123+
data.verify(this);
124+
} catch (Exception e) {
125+
Log.w(TAG, "Verification failed", e);
126+
finish();
127+
return;
128+
}
72129

73130
// This makes the dialog take up the full width
74131
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
@@ -77,57 +134,28 @@ protected void onCreate(Bundle savedInstanceState) {
77134
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
78135
getWindow().setAttributes(lp);
79136

80-
account = new Account(getIntent().getStringExtra(KEY_ACCOUNT_NAME),
81-
getIntent().getStringExtra(KEY_ACCOUNT_TYPE));
82-
packageName = getIntent().getStringExtra(KEY_ANDROID_PACKAGE_NAME);
83-
service = getIntent().getStringExtra(KEY_AUTHTOKEN);
84-
if (getIntent().hasExtra(EXTRA_CONSENT_DATA)) {
85-
try {
86-
consentData = ConsentData.ADAPTER.decode(getIntent().getByteArrayExtra(EXTRA_CONSENT_DATA));
87-
} catch (Exception e) {
88-
Log.w(TAG, e);
89-
}
90-
} else {
91-
Log.d(TAG, "No Consent details attached");
92-
}
93-
94137
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
95-
nm.cancel(packageName.hashCode());
138+
nm.cancel(data.packageName.hashCode());
96139

97-
if (getIntent().hasExtra(EXTRA_FROM_ACCOUNT_MANAGER)) fromAccountManager = true;
98-
int callerUid = getIntent().getIntExtra(KEY_CALLER_UID, 0);
99-
packageName = PackageUtils.getAndCheckPackage(this, packageName, getIntent().getIntExtra(KEY_CALLER_UID, 0), getIntent().getIntExtra(KEY_CALLER_PID, 0));
100-
authManager = new AuthManager(this, account.name, packageName, service);
140+
authManager = new AuthManager(this, data.accountName, data.packageName, data.service);
101141

102-
// receive package info
103-
PackageManager packageManager = getPackageManager();
104-
ApplicationInfo applicationInfo;
105-
try {
106-
applicationInfo = packageManager.getApplicationInfo(packageName, 0);
107-
} catch (PackageManager.NameNotFoundException e) {
108-
Log.w(TAG, "Failed to find package " + packageName, e);
109-
finish();
110-
return;
111-
}
112-
CharSequence appLabel = packageManager.getApplicationLabel(applicationInfo);
113-
Drawable appIcon = packageManager.getApplicationIcon(applicationInfo);
114-
Bitmap profileIcon = PeopleManager.getOwnerAvatarBitmap(this, account.name, false);
142+
Bitmap profileIcon = PeopleManager.getOwnerAvatarBitmap(this, data.accountName, false);
115143

116144
// receive profile icon
117145
if (profileIcon != null) {
118146
((ImageView) findViewById(R.id.account_photo)).setImageBitmap(profileIcon);
119147
} else {
120148
new Thread(() -> {
121-
final Bitmap profileIcon1 = PeopleManager.getOwnerAvatarBitmap(AskPermissionActivity.this, account.name, true);
149+
final Bitmap profileIcon1 = PeopleManager.getOwnerAvatarBitmap(AskPermissionActivity.this, data.accountName, true);
122150
runOnUiThread(() -> ((ImageView) findViewById(R.id.account_photo)).setImageBitmap(profileIcon1));
123151
}).start();
124152
}
125153

126-
((ImageView) findViewById(R.id.app_icon)).setImageDrawable(appIcon);
154+
((ImageView) findViewById(R.id.app_icon)).setImageDrawable(data.appIcon);
127155
if (isOAuth()) {
128-
((TextView) findViewById(R.id.title)).setText(getString(R.string.ask_scope_permission_title, appLabel));
156+
((TextView) findViewById(R.id.title)).setText(getString(R.string.ask_scope_permission_title, data.appLabel));
129157
} else {
130-
((TextView) findViewById(R.id.title)).setText(getString(R.string.ask_service_permission_title, appLabel));
158+
((TextView) findViewById(R.id.title)).setText(getString(R.string.ask_service_permission_title, data.appLabel));
131159
}
132160
findViewById(android.R.id.button1).setOnClickListener(v -> onAllow());
133161
findViewById(android.R.id.button2).setOnClickListener(v -> onDeny());
@@ -142,12 +170,12 @@ public void onAllow() {
142170
findViewById(R.id.no_progress_bar).setVisibility(GONE);
143171
new Thread(() -> {
144172
try {
145-
AuthResponse response = authManager.requestAuth(fromAccountManager);
173+
AuthResponse response = authManager.requestAuth(data.fromAccountManager);
146174
Bundle result = new Bundle();
147175
result.putString(KEY_AUTHTOKEN, response.auth);
148-
result.putString(KEY_ACCOUNT_NAME, account.name);
149-
result.putString(KEY_ACCOUNT_TYPE, account.type);
150-
result.putString(KEY_ANDROID_PACKAGE_NAME, packageName);
176+
result.putString(KEY_ACCOUNT_NAME, data.accountName);
177+
result.putString(KEY_ACCOUNT_TYPE, data.accountType);
178+
result.putString(KEY_ANDROID_PACKAGE_NAME, data.packageName);
151179
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
152180
setAccountAuthenticatorResult(result);
153181
} catch (IOException e) {
@@ -164,20 +192,20 @@ public void onDeny() {
164192

165193
@Override
166194
public void finish() {
167-
if (packageName != null) {
195+
if (data.packageName != null) {
168196
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
169-
nm.cancel(packageName.hashCode());
197+
nm.cancel(data.packageName.hashCode());
170198
}
171199
super.finish();
172200
}
173201

174202
private boolean isOAuth() {
175-
return service.startsWith("oauth2:") || service.startsWith("oauth:");
203+
return data.service.startsWith("oauth2:") || data.service.startsWith("oauth:");
176204
}
177205

178206
private String getScopeLabel(String scope) {
179-
if (consentData != null) {
180-
for (ConsentData.ScopeDetails scopeDetails : consentData.scopes) {
207+
if (data.consentData != null) {
208+
for (ConsentData.ScopeDetails scopeDetails : data.consentData.scopes) {
181209
if (scope.equals(scopeDetails.id)) {
182210
return scopeDetails.title;
183211
}
@@ -198,8 +226,8 @@ private String getScopeLabel(String scope) {
198226
}
199227

200228
private String getScopeDescription(String scope) {
201-
if (consentData != null) {
202-
for (ConsentData.ScopeDetails scopeDetails : consentData.scopes) {
229+
if (data.consentData != null) {
230+
for (ConsentData.ScopeDetails scopeDetails : data.consentData.scopes) {
203231
if (scope.equals(scopeDetails.id)) {
204232
return scopeDetails.description;
205233
}
@@ -221,18 +249,18 @@ private class PermissionAdapter extends BaseAdapter {
221249
@Override
222250
public int getCount() {
223251
if (isOAuth()) {
224-
return service.split(" ").length;
252+
return data.service.split(" ").length;
225253
}
226254
return 1;
227255
}
228256

229257
@Override
230258
public String getItem(int position) {
231259
if (isOAuth()) {
232-
String tokens = service.split(":", 2)[1];
260+
String tokens = data.service.split(":", 2)[1];
233261
return tokens.split(" ")[position];
234262
}
235-
return service;
263+
return data.service;
236264
}
237265

238266
@Override

0 commit comments

Comments
 (0)