mirror of
https://github.com/M66B/FairEmail.git
synced 2025-03-19 10:25:29 +00:00
Added option for custom EHLO identification
This commit is contained in:
parent
4493d77d33
commit
6110ff0aa6
9 changed files with 2287 additions and 11 deletions
2223
app/schemas/eu.faircode.email.DB/154.json
Normal file
2223
app/schemas/eu.faircode.email.DB/154.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -61,7 +61,7 @@ import io.requery.android.database.sqlite.SQLiteDatabase;
|
|||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 153,
|
||||
version = 154,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
|
@ -1538,6 +1538,13 @@ public abstract class DB extends RoomDatabase {
|
|||
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("ALTER TABLE `identity` ADD COLUMN `unicode` INTEGER NOT NULL DEFAULT 0");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(153, 154) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||
db.execSQL("ALTER TABLE `identity` ADD COLUMN `ehlo` TEXT");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ public class EmailService implements AutoCloseable {
|
|||
private boolean insecure;
|
||||
private boolean harden;
|
||||
private boolean useip;
|
||||
private String ehlo;
|
||||
private boolean debug;
|
||||
private Properties properties;
|
||||
private Session isession;
|
||||
|
@ -231,8 +232,9 @@ public class EmailService implements AutoCloseable {
|
|||
properties.put("mail." + protocol + ".ignorebodystructuresize", Boolean.toString(enabled));
|
||||
}
|
||||
|
||||
void setUseIp(boolean enabled) {
|
||||
useip = enabled;
|
||||
void setUseIp(boolean enabled, String host) {
|
||||
this.useip = enabled;
|
||||
this.ehlo = host;
|
||||
}
|
||||
|
||||
void setLeaveOnServer(boolean keep) {
|
||||
|
@ -503,14 +505,15 @@ public class EmailService implements AutoCloseable {
|
|||
// https://tools.ietf.org/html/rfc5321#section-4.1.3
|
||||
String haddr = (address instanceof Inet4Address ? "[127.0.0.1]" : "[IPv6:::1]");
|
||||
|
||||
properties.put("mail." + protocol + ".localhost", useip ? haddr : hdomain);
|
||||
properties.put("mail." + protocol + ".localhost",
|
||||
ehlo == null ? (useip ? haddr : hdomain) : ehlo);
|
||||
Log.i("Using localhost=" + properties.getProperty("mail." + protocol + ".localhost"));
|
||||
|
||||
iservice = isession.getTransport(protocol);
|
||||
try {
|
||||
iservice.connect(address.getHostAddress(), port, user, password);
|
||||
} catch (MessagingException ex) {
|
||||
if (ConnectionHelper.isSyntacticallyInvalid(ex)) {
|
||||
if (ehlo == null && ConnectionHelper.isSyntacticallyInvalid(ex)) {
|
||||
properties.put("mail." + protocol + ".localhost", useip ? hdomain : haddr);
|
||||
Log.i("Fallback localhost=" + properties.getProperty("mail." + protocol + ".localhost"));
|
||||
try {
|
||||
|
|
|
@ -84,6 +84,7 @@ public class EntityIdentity {
|
|||
public String fingerprint;
|
||||
@NonNull
|
||||
public Boolean use_ip = true; // instead of domain name
|
||||
public String ehlo;
|
||||
@NonNull
|
||||
public Boolean synchronize;
|
||||
@NonNull
|
||||
|
@ -183,6 +184,7 @@ public class EntityIdentity {
|
|||
json.put("realm", realm);
|
||||
json.put("fingerprint", fingerprint);
|
||||
json.put("use_ip", use_ip);
|
||||
json.put("ehlo", ehlo);
|
||||
|
||||
json.put("synchronize", synchronize);
|
||||
json.put("primary", primary);
|
||||
|
@ -234,6 +236,8 @@ public class EntityIdentity {
|
|||
identity.fingerprint = json.getString("fingerprint");
|
||||
if (json.has("use_ip"))
|
||||
identity.use_ip = json.getBoolean("use_ip");
|
||||
if (json.has("ehlo"))
|
||||
identity.ehlo = json.getString("ehlo");
|
||||
|
||||
identity.synchronize = json.getBoolean("synchronize");
|
||||
identity.primary = json.getBoolean("primary");
|
||||
|
@ -271,6 +275,7 @@ public class EntityIdentity {
|
|||
this.password.equals(other.password) &&
|
||||
Objects.equals(this.realm, other.realm) &&
|
||||
this.use_ip == other.use_ip &&
|
||||
Objects.equals(this.ehlo, other.ehlo) &&
|
||||
this.synchronize.equals(other.synchronize) &&
|
||||
this.primary.equals(other.primary) &&
|
||||
this.sender_extra.equals(sender_extra) &&
|
||||
|
|
|
@ -102,6 +102,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
private Button btnOAuth;
|
||||
private EditText etRealm;
|
||||
private CheckBox cbUseIp;
|
||||
private EditText etEhlo;
|
||||
|
||||
private CheckBox cbSynchronize;
|
||||
private CheckBox cbPrimary;
|
||||
|
@ -192,6 +193,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
btnOAuth = view.findViewById(R.id.btnOAuth);
|
||||
etRealm = view.findViewById(R.id.etRealm);
|
||||
cbUseIp = view.findViewById(R.id.cbUseIp);
|
||||
etEhlo = view.findViewById(R.id.etEhlo);
|
||||
|
||||
cbSynchronize = view.findViewById(R.id.cbSynchronize);
|
||||
cbPrimary = view.findViewById(R.id.cbPrimary);
|
||||
|
@ -258,6 +260,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
etPort.setText(Integer.toString(provider.smtp.port));
|
||||
rgEncryption.check(provider.smtp.starttls ? R.id.radio_starttls : R.id.radio_ssl);
|
||||
cbUseIp.setChecked(provider.useip);
|
||||
etEhlo.setText(null);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -379,6 +382,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
etPort.setText(position == 0 ? null : Integer.toString(provider.smtp.port));
|
||||
rgEncryption.check(provider.smtp.starttls ? R.id.radio_starttls : R.id.radio_ssl);
|
||||
cbUseIp.setChecked(provider.useip);
|
||||
etEhlo.setText(null);
|
||||
|
||||
EntityAccount account = (EntityAccount) spAccount.getSelectedItem();
|
||||
if (account == null ||
|
||||
|
@ -537,6 +541,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
etPort.setText(Integer.toString(provider.smtp.port));
|
||||
rgEncryption.check(provider.smtp.starttls ? R.id.radio_starttls : R.id.radio_ssl);
|
||||
cbUseIp.setChecked(provider.useip);
|
||||
etEhlo.setText(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -593,6 +598,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
args.putString("realm", etRealm.getText().toString());
|
||||
args.putString("fingerprint", cbTrust.isChecked() ? (String) cbTrust.getTag() : null);
|
||||
args.putBoolean("use_ip", cbUseIp.isChecked());
|
||||
args.putString("ehlo", etEhlo.getText().toString());
|
||||
args.putString("signature", signature);
|
||||
args.putBoolean("synchronize", cbSynchronize.isChecked());
|
||||
args.putBoolean("primary", cbPrimary.isChecked());
|
||||
|
@ -643,6 +649,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
String realm = args.getString("realm");
|
||||
String fingerprint = args.getString("fingerprint");
|
||||
boolean use_ip = args.getBoolean("use_ip");
|
||||
String ehlo = args.getString("ehlo");
|
||||
boolean synchronize = args.getBoolean("synchronize");
|
||||
boolean primary = args.getBoolean("primary");
|
||||
|
||||
|
@ -705,6 +712,9 @@ public class FragmentIdentity extends FragmentBase {
|
|||
if (TextUtils.isEmpty(realm))
|
||||
realm = null;
|
||||
|
||||
if (TextUtils.isEmpty(ehlo))
|
||||
ehlo = null;
|
||||
|
||||
if (TextUtils.isEmpty(sender_extra_regex))
|
||||
sender_extra_regex = null;
|
||||
|
||||
|
@ -763,6 +773,8 @@ public class FragmentIdentity extends FragmentBase {
|
|||
return true;
|
||||
if (!Objects.equals(identity.use_ip, use_ip))
|
||||
return true;
|
||||
if (!Objects.equals(identity.ehlo, ehlo))
|
||||
return true;
|
||||
if (!Objects.equals(identity.synchronize, synchronize))
|
||||
return true;
|
||||
if (!Objects.equals(identity.primary, (identity.synchronize && primary)))
|
||||
|
@ -793,7 +805,8 @@ public class FragmentIdentity extends FragmentBase {
|
|||
!Objects.equals(identity.certificate_alias, certificate) ||
|
||||
!Objects.equals(realm, identityRealm) ||
|
||||
!Objects.equals(identity.fingerprint, fingerprint) ||
|
||||
use_ip != identity.use_ip));
|
||||
use_ip != identity.use_ip) ||
|
||||
!Objects.equals(identity.ehlo, ehlo));
|
||||
Log.i("Identity check=" + check);
|
||||
|
||||
Long last_connected = null;
|
||||
|
@ -806,7 +819,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
String protocol = (starttls ? "smtp" : "smtps");
|
||||
try (EmailService iservice = new EmailService(
|
||||
context, protocol, realm, insecure, EmailService.PURPOSE_CHECK, true)) {
|
||||
iservice.setUseIp(use_ip);
|
||||
iservice.setUseIp(use_ip, ehlo);
|
||||
iservice.connect(
|
||||
host, Integer.parseInt(port),
|
||||
auth, provider,
|
||||
|
@ -848,6 +861,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
identity.realm = realm;
|
||||
identity.fingerprint = fingerprint;
|
||||
identity.use_ip = use_ip;
|
||||
identity.ehlo = ehlo;
|
||||
identity.synchronize = synchronize;
|
||||
identity.primary = (identity.synchronize && primary);
|
||||
|
||||
|
@ -1056,6 +1070,7 @@ public class FragmentIdentity extends FragmentBase {
|
|||
}
|
||||
|
||||
cbUseIp.setChecked(identity == null ? true : identity.use_ip);
|
||||
etEhlo.setText(identity == null ? null : identity.ehlo);
|
||||
cbSynchronize.setChecked(identity == null ? true : identity.synchronize);
|
||||
cbPrimary.setChecked(identity == null ? true : identity.primary);
|
||||
|
||||
|
|
|
@ -308,7 +308,7 @@ public class FragmentQuickSetup extends FragmentBase {
|
|||
String iprotocol = provider.smtp.starttls ? "smtp" : "smtps";
|
||||
try (EmailService iservice = new EmailService(
|
||||
context, iprotocol, null, false, EmailService.PURPOSE_CHECK, true)) {
|
||||
iservice.setUseIp(provider.useip);
|
||||
iservice.setUseIp(provider.useip, null);
|
||||
iservice.connect(
|
||||
provider.smtp.host, provider.smtp.port,
|
||||
EmailService.AUTH_TYPE_PASSWORD, null,
|
||||
|
|
|
@ -466,7 +466,7 @@ public class ServiceSend extends ServiceBase {
|
|||
// Create transport
|
||||
try (EmailService iservice = new EmailService(
|
||||
this, ident.getProtocol(), ident.realm, ident.insecure, debug)) {
|
||||
iservice.setUseIp(ident.use_ip);
|
||||
iservice.setUseIp(ident.use_ip, ident.ehlo);
|
||||
iservice.setUnicode(ident.unicode);
|
||||
|
||||
// Connect transport
|
||||
|
|
|
@ -488,6 +488,28 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cbUseIp" />
|
||||
|
||||
<eu.faircode.email.FixedTextView
|
||||
android:id="@+id/tvEhlo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_ehlo"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvUseIpHint" />
|
||||
|
||||
<eu.faircode.email.EditTextPlain
|
||||
android:id="@+id/etEhlo"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints="name"
|
||||
android:hint="@string/title_optional"
|
||||
android:inputType="text"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvEhlo" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbSynchronize"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -495,7 +517,7 @@
|
|||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_enabled"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvUseIpHint" />
|
||||
app:layout_constraintTop_toBottomOf="@id/etEhlo" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbPrimary"
|
||||
|
@ -760,7 +782,7 @@
|
|||
tvSmtp,tvHost,etHost,rgEncryption,cbInsecure,tvInsecureRemark,tvPort,etPort,
|
||||
tvUser,etUser,tvPassword,tilPassword,btnCertificate,tvCertificate,btnOAuth,
|
||||
tvRealm,etRealm,
|
||||
cbUseIp,tvUseIpHint,
|
||||
cbUseIp,tvUseIpHint,tvEhlo,etEhlo,
|
||||
cbSynchronize,cbPrimary,
|
||||
cbSenderExtra,tvSenderExtra,etSenderExtra,tvSenderExtraHint,
|
||||
tvReplyTo,etReplyTo,tvCc,etCc,tvCcHint,tvBcc,etBcc,tvBccHint,cbUnicode" />
|
||||
|
|
|
@ -573,6 +573,7 @@
|
|||
<string name="title_client_certificate">Client certificate</string>
|
||||
<string name="title_realm">Realm</string>
|
||||
<string name="title_use_ip">Use local IP address instead of host name</string>
|
||||
<string name="title_ehlo">Custom HELO/EHLO identification</string>
|
||||
<string name="title_primary">Primary</string>
|
||||
<string name="title_primary_account">Primary (default account)</string>
|
||||
<string name="title_primary_identity">Primary (default identity)</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue