Basic support for importing Apple's .mobileconfig files

pull/214/head
M66B 2 years ago
parent 304a765b4a
commit 137aba6df3

@ -21,6 +21,7 @@ package eu.faircode.email;
import static android.app.Activity.RESULT_OK;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_GMAIL;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@ -60,6 +61,7 @@ import androidx.cardview.widget.CardView;
import androidx.constraintlayout.widget.Group;
import androidx.documentfile.provider.DocumentFile;
import androidx.lifecycle.ViewModelProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.preference.PreferenceManager;
import com.google.android.material.textfield.TextInputLayout;
@ -655,6 +657,9 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere
if ("k9s".equals(ext)) {
handleK9Import(uri);
return;
} else if ("mobileconfig".equals(ext)) {
handleAppleImport(uri);
return;
}
}
} catch (Throwable ex) {
@ -1514,6 +1519,183 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere
}.execute(this, args, "setup:k9");
}
private void handleAppleImport(Uri uri) {
Bundle args = new Bundle();
args.putParcelable("uri", uri);
ViewModelExport vme = new ViewModelProvider(getActivity()).get(ViewModelExport.class);
args.putString("password", vme.getPassword());
new SimpleTask<EntityAccount>() {
@Override
protected EntityAccount onExecute(Context context, Bundle args) throws Throwable {
Uri uri = args.getParcelable("uri");
String password = args.getString("password");
EntityAccount account = new EntityAccount();
EntityIdentity identity = new EntityIdentity();
ContentResolver resolver = context.getContentResolver();
InputStream is = resolver.openInputStream(uri);
if (is == null)
throw new FileNotFoundException(uri.toString());
try (InputStream bis = new BufferedInputStream(is)) {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xml = factory.newPullParser();
xml.setInput(new InputStreamReader(bis));
account.auth_type = AUTH_TYPE_PASSWORD;
account.password = password;
account.encryption = EmailService.ENCRYPTION_STARTTLS;
account.synchronize = false;
account.primary = false;
identity.auth_type = AUTH_TYPE_PASSWORD;
identity.password = password;
identity.encryption = EmailService.ENCRYPTION_STARTTLS;
identity.synchronize = false;
identity.primary = true;
// https://developer.apple.com/documentation/devicemanagement/mail
String key = null;
int eventType = xml.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
String name = xml.getName();
if ("key".equals(name)) {
eventType = xml.next();
key = (eventType == XmlPullParser.TEXT ? xml.getText() : null);
} else if (key != null &&
("string".equals(name) || "integer".equals(name))) {
eventType = xml.next();
if (eventType == XmlPullParser.TEXT) {
String value = xml.getText();
eventType = xml.next();
if (eventType == XmlPullParser.END_TAG) {
Log.i("mobileconfig " + key + "=" + value);
switch (key) {
case "allowMailDrop":
break;
case "disableMailRecentsSyncing":
break;
case "EmailAccountDescription":
account.name = value;
break;
case "EmailAccountName":
identity.name = value;
break;
case "EmailAccountType": // required
if ("EmailTypeIMAP".equals(value))
account.protocol = EntityAccount.TYPE_IMAP;
else if ("EmailTypePOP".equals(value))
account.protocol = EntityAccount.TYPE_POP;
break;
case "EmailAddress":
String[] email = value.split(",");
if (email.length > 0)
identity.email = email[0];
break;
case "IncomingMailServerAuthentication": // required
// EmailAuthNone, EmailAuthPassword, EmailAuthCRAMMD5, EmailAuthNTLM, EmailAuthHTTPMD5
break;
case "IncomingMailServerHostName": // required
account.host = value;
break;
case "IncomingMailServerIMAPPathPrefix":
break;
case "IncomingMailServerPortNumber":
account.port = Integer.parseInt(value);
break;
case "IncomingMailServerUsername":
account.user = value;
break;
case "IncomingMailServerUseSSL":
account.encryption = EmailService.ENCRYPTION_SSL;
break;
case "IncomingPassword":
account.password = value;
break;
case "OutgoingMailServerAuthentication": // required
// EmailAuthNone, EmailAuthPassword, EmailAuthCRAMMD5, EmailAuthNTLM, EmailAuthHTTPMD5
break;
case "OutgoingMailServerHostName": // required
identity.host = value;
break;
case "OutgoingMailServerPortNumber":
identity.port = Integer.parseInt(value);
break;
case "OutgoingMailServerUsername":
identity.user = value;
break;
case "OutgoingMailServerUseSSL":
identity.encryption = EmailService.ENCRYPTION_SSL;
break;
case "OutgoingPassword":
identity.password = value;
break;
case "OutgoingPasswordSameAsIncomingPassword":
identity.password = account.password;
break;
}
}
} else
key = null;
} else if (key != null && "true".equals(name)) {
Log.i("mobileconfig " + key + "=" + name);
} else
key = null;
}
eventType = xml.next();
}
if (account.port == null)
account.port = 993;
if (account.password == null)
account.password = "";
if (identity.port == null)
identity.port = 587;
if (identity.password == null)
identity.password = "";
}
DB db = DB.getInstance(context);
try {
db.beginTransaction();
account.id = db.account().insertAccount(account);
identity.account = account.id;
identity.id = db.identity().insertIdentity(identity);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
return account;
}
@Override
protected void onExecuted(Bundle args, EntityAccount account) {
if (account == null)
return;
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
lbm.sendBroadcast(
new Intent(ActivitySetup.ACTION_EDIT_ACCOUNT)
.putExtra("id", account.id)
.putExtra("protocol", account.protocol));
}
@Override
protected void onException(Bundle args, Throwable ex) {
Log.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(this, args, "setup:apple");
}
private void askPassword(final boolean export) {
final Context context = getContext();
Intent intent = (export ? getIntentExport(context) : getIntentImport(context));

Loading…
Cancel
Save