Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ public class ServiceSinkhole extends VpnService {
private static final int NOTIFY_DOH_ERROR = 11;
private static final int NOTIFY_WG_ERROR = 12;
private static final int NOTIFY_LOCAL_NETWORK = 13;
private static final int NOTIFY_PRIVATE_DNS = 14;

public static final String EXTRA_COMMAND = "Command";
private static final String EXTRA_REASON = "Reason";
Expand Down Expand Up @@ -706,7 +707,20 @@ private void stop(boolean temporary) {
net.kollnig.missioncontrol.wg.WgEgress.INSTANCE.stop(
() -> { jni_wireguard_stop(); return kotlin.Unit.INSTANCE; });
jni_wireguard_required(false);
// WgEgress clears its error as it tears the tunnel down, so the
// state listener already retracts this one; the call remains for
// the case it cannot see, a start that failed without ever
// producing a tunnel, where stop() finds nothing to notify about.
clearWireGuardErrorNotification();
// The other two are config warnings nothing else retracts, and
// both describe a tunnel that is no longer running — but leave
// them on a temporary stop (a call, say): the VPN is coming
// straight back, and re-posting a cancelled notification alerts
// again, so the user would be buzzed on every call.
if (!temporary) {
clearLocalNetworkNotification();
clearPrivateDnsNotification();
}
unprepare();

// Stop DoH proxy
Expand Down Expand Up @@ -1674,6 +1688,18 @@ private Builder getBuilder(List<Rule> listAllowed, List<Rule> listRule) {
} else
clearLocalNetworkNotification();

// Blocking port 853 is what lets us keep seeing DNS: with Private DNS on
// "automatic", Android falls back to plaintext and detection carries on.
// In "hostname" mode it does not fall back — the user picked that
// resolver explicitly, so DNS simply fails and nothing resolves. That
// looks like TC broke the connection, with no hint of why, so say it.
if (prefs.getBoolean("block_dot", true) && Util.isPrivateDnsHostnameMode(this)) {
Log.w(TAG, "Private DNS set to a hostname: DoT is blocked and Android will not" +
" fall back to plaintext DNS, so name resolution fails");
showPrivateDnsNotification(Util.getPrivateDnsSpecifier(this));
} else
clearPrivateDnsNotification();

// Dynamically exclude carrier ePDG IPs so Wi-Fi calling works globally.
// ePDG domains follow 3GPP standard: epdg.epc.mnc{MNC}.mcc{MCC}.pub.3gppnetwork.org
// TC excludes itself from the VPN (addDisallowedApplication), so this DNS resolution
Expand Down Expand Up @@ -3776,6 +3802,46 @@ private void clearLocalNetworkNotification() {
NotificationManagerCompat.from(this).cancel(NOTIFY_LOCAL_NETWORK);
}

/**
* Private DNS is pinned to a hostname while we block DoT, which leaves the
* device with no working resolver. Opens the network settings, where the
* setting lives; naming the resolver makes clear which one is meant.
*/
private void showPrivateDnsNotification(String specifier) {
Intent settings = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
if (settings.resolveActivity(getPackageManager()) == null)
settings = new Intent(Settings.ACTION_WIFI_SETTINGS);
PendingIntent pi = PendingIntentCompat.getActivity(this, NOTIFY_PRIVATE_DNS, settings,
PendingIntent.FLAG_UPDATE_CURRENT);

String detail = getString(R.string.msg_private_dns_notify,
specifier != null ? specifier : getString(R.string.msg_private_dns_unknown_resolver));

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
.setContentTitle(getString(R.string.msg_private_dns_title))
.setContentText(detail)
.setContentIntent(pi)
.setColor(getResources().getColor(R.color.colorTrackerControl))
.setOngoing(false)
.setAutoCancel(true)
// Rebuilt on every network change; alert once, then sit quietly.
.setOnlyAlertOnce(true);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
.setVisibility(NotificationCompat.VISIBILITY_SECRET);

NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
notification.bigText(detail);

Util.notify(this, NOTIFY_PRIVATE_DNS, notification.build());
}

private void clearPrivateDnsNotification() {
NotificationManagerCompat.from(this).cancel(NOTIFY_PRIVATE_DNS);
}

private void showUpdateNotification(String name, String url) {
if (Util.isFDroidInstall())
return;
Expand Down
24 changes: 12 additions & 12 deletions app/src/main/java/eu/faircode/netguard/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,6 @@ public static boolean isEU(String country) {
return (country != null && listEU.contains(country.toUpperCase()));
}

public static boolean isPrivateDns(Context context) {
String dns_mode = Settings.Global.getString(context.getContentResolver(), "private_dns_mode");
Log.i(TAG, "Private DNS mode=" + dns_mode);
if (dns_mode == null)
dns_mode = "off";
return (!"off".equals(dns_mode));
}

public static String getNetworkGeneration(int networkType) {
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_1xRTT:
Expand Down Expand Up @@ -564,12 +556,20 @@ public static String getProtocolName(int protocol, int version, boolean brief) {
return ((brief ? b : p) + (version > 0 ? version : ""));
}

public static String getPrivateDnsSpecifier(Context context) {
/**
* Whether Android's Private DNS is pinned to a specific resolver hostname
* ("hostname" mode) rather than left on "automatic" or turned off. In this
* mode Android does not fall back to plaintext DNS when DoT is blocked.
*/
public static boolean isPrivateDnsHostnameMode(Context context) {
String dns_mode = Settings.Global.getString(context.getContentResolver(), "private_dns_mode");
if ("hostname".equals(dns_mode))
return Settings.Global.getString(context.getContentResolver(), "private_dns_specifier");
else
return "hostname".equals(dns_mode);
}

public static String getPrivateDnsSpecifier(Context context) {
if (!isPrivateDnsHostnameMode(context))
return null;
return Settings.Global.getString(context.getContentResolver(), "private_dns_specifier");
}

public interface DoubtListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,20 +242,8 @@ private void setupSlides() {
// }
// }

// 7. Private DNS (Mandatory)
boolean privateDnsEnabled = Util.isPrivateDns(this);
if (privateDnsEnabled) {
slides.add(new Slide(
R.string.onboarding_privatedns_title,
getText(R.string.onboarding_privatedns_title),
android.text.TextUtils.concat(getText(R.string.onboarding_privatedns_desc), "\n\n",
android.text.Html
.fromHtml("<b>" + getString(R.string.onboarding_privatedns_instruction) + "</b>")),
R.drawable.screen,
getString(R.string.onboarding_privatedns_action),
R.string.onboarding_privatedns_skip_msg,
null));
}
// 7. Private DNS - no longer asked about: DoT (port 853) is blocked by
// default, so Android falls back to plaintext DNS on its own.

// 8. Timeline
slides.add(new Slide(
Expand Down Expand Up @@ -394,25 +382,6 @@ private void refreshSlides() {
// };
// }

// 7. Private DNS
if (slide.titleResId == R.string.onboarding_privatedns_title) {
boolean privateDnsEnabled = Util.isPrivateDns(this);
slide.actionButtonText = privateDnsEnabled ? getString(R.string.onboarding_privatedns_action)
: getString(R.string.onboarding_action_disabled);
slide.warningResId = privateDnsEnabled ? R.string.onboarding_privatedns_skip_msg : 0;
if (privateDnsEnabled) {
slide.actionListener = v -> {
Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
if (intent.resolveActivity(getPackageManager()) == null) {
intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
}
startActivity(intent);
};
} else {
slide.actionListener = null;
}
}

// Lockdown
if (slide.titleResId == R.string.onboarding_lockdown_title) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/net/kollnig/missioncontrol/wg/WgEgress.kt
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,11 @@ object WgEgress {
currentKeepaliveAlwaysOn = false
lastCheapRecoveryMs = 0
verificationGeneration++
// An error describes a tunnel that no longer exists. Listeners check
// lastError before isRunning — deliberately, so a start that fails
// without ever producing a tunnel still reports — so leaving it set
// here kept a stopped tunnel reporting its final error forever.
lastError = null
if (t != null) {
try {
t.stop()
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/values-fi-rFI/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,6 @@ Ystävällisin terveisin,\n\n]]></string>
<string name="onboarding_notify_desc">Salli ilmoitukset, jotta voit nähdä reaaliaikaiset päivitykset ja hallita suojausta suoraan tilapalkista.</string>
<string name="onboarding_notify_action">Salli ilmoitukset</string>
<string name="onboarding_notify_sure">Ilman ilmoituslupaa et voi nähdä reaaliaikaisia päivityksiä tai hallita suojausta tilapalkista. Oletko varma?</string>
<string name="onboarding_privatedns_title">Poista yksityinen DNS käytöstä</string>
<string name="onboarding_privatedns_desc">Androidin ”Yksityinen DNS” -ominaisuus häiritsee TrackerControlin kykyä estää seurantalaitteita. Tämä asetus <b>on</b> asetettava ”Pois päältä” -tilaan, jotta voit jatkaa.</string>
<string name="onboarding_privatedns_instruction">Asetukset -&gt; Verkko &amp; Internet -&gt; Yksityinen DNS -&gt; POIS.</string>
<string name="onboarding_privatedns_action">Avaa DNS-asetukset</string>
<string name="onboarding_privatedns_skip_title">Ohita yksityisen DNS:n päältä poisto?</string>
<string name="onboarding_privatedns_skip_msg">Jatkaessasi yksityisen DNS:n ollessa käytössä TrackerControlin toiminta rajoittuu huomattavasti. Suurin osa seurannasta ei esty, vaan jäljelle jää vain seurantakirjaston analysointi. Lisäksi VPN-suodatin poistetaan käytöstä perusominaisuuksien toimivuuden varmistamiseksi.</string>
<string name="onboarding_network_title">Rajoittamaton verkko</string>
<string name="onboarding_network_desc">Tietojen tallennusasetukset voivat estää TrackerControlin toimimasta oikein taustalla. Anna rajoittamaton käyttöoikeus, jotta saat luotettavimman suojan.</string>
<string name="onboarding_network_action">Myönnä rajoittamaton käyttöoikeus</string>
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -541,8 +541,6 @@ Cordialement,\n\n]]></string>
<string name="onboarding_battery_sure">Sans désactiver l\'optimisation de la batterie, TrackerControl peut être couper par Android à tout moment. Êtes-vous sûr de vouloir continuer ?</string>
<string name="onboarding_notify_title">Restez informé</string>
<string name="onboarding_notify_action">Autoriser les notifications</string>
<string name="onboarding_privatedns_title">Désactiver le DNS privé</string>
<string name="onboarding_privatedns_action">Ouvrir les paramètres DNS</string>
<string name="onboarding_lockdown_title">Paramètres de verrouillage VPN</string>
<string name="onboarding_lockdown_action">Ouvrir les paramètres VPN</string>
<string name="onboarding_dns_title">DNS sécurisé (fonctionnalité béta ; peut ne pas fonctionner comme prévu)</string>
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/values-pt-rBR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,6 @@ O seu tráfego de internet não está sendo enviado para um servidor VPN remoto.
<string name="onboarding_notify_desc">Permite notificações para ver atualizações em tempo real e controlar a proteção diretamente na barra de status.</string>
<string name="onboarding_notify_action">Permitir notificações</string>
<string name="onboarding_notify_sure">Sem permissões de notificação, você não poderá ver atualizações ou proteção de controle em tempo real na barra de status. Tem certeza?</string>
<string name="onboarding_privatedns_title">Desabilitar DNS privado</string>
<string name="onboarding_privatedns_desc">O recurso \"DNS privado\" do Android interfere com a capacidade do TrackerControl de bloquear rastreadores. Esta configuração <b>deve ser definida como</b> desativada para continuar.</string>
<string name="onboarding_privatedns_instruction">Configurações -&gt; Rede &amp; Internet -&gt; DNS privado -&gt; Desligado.</string>
<string name="onboarding_privatedns_action">Abrir configurações de DNS</string>
<string name="onboarding_privatedns_skip_title">Ignorar o DNS privado desativado?</string>
<string name="onboarding_privatedns_skip_msg">Prosseguir com DNS privado habilitado irá restringir fortemente o TrackerControl. A maioria do rastreamento não será bloqueada, deixando apenas a análise da biblioteca de rastreamento. Além disso, o filtro da VPN será desativado para garantir as funcionalidades básicas.</string>
<string name="onboarding_network_title">Rede irrestrita</string>
<string name="onboarding_network_desc">A Economia de dados pode impedir que o TrackerControl funcione corretamente em segundo plano. Conceda acesso irrestrito para uma proteção mais confiável.</string>
<string name="onboarding_network_action">Conceder acesso irrestrito</string>
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/values-ru-rRU/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -434,12 +434,6 @@
<string name="onboarding_notify_desc">Разрешить уведомления, чтобы видеть обновления в режиме реального времени и управлять защитой непосредственно из строки состояния.</string>
<string name="onboarding_notify_action">Разрешить уведомления</string>
<string name="onboarding_notify_sure">Без разрешения на показ уведомлений вы не сможете видеть обновления или управлять защитой из строки состояния. Вы уверены?</string>
<string name="onboarding_privatedns_title">Отключить приватный DNS</string>
<string name="onboarding_privatedns_desc">Android-функция \"Private DNS\" препятствует возможности TrackerControl блокировать трекеры. Эта настройка <b>должна быть</b> \"Выключено\" для продолжения.</string>
<string name="onboarding_privatedns_instruction">Настройки -&gt; Сеть &amp; Интернет -&gt; Частный DNS -&gt; Выключить.</string>
<string name="onboarding_privatedns_action">Открыть настройки DNS</string>
<string name="onboarding_privatedns_skip_title">Пропустить отключение приватного DNS?</string>
<string name="onboarding_privatedns_skip_msg">Включение приватного DNS сильно ограничит TrackerControl. Большинство треков не будет блокироваться, оставляя только анализ библиотеки трекеров. Кроме того, фильтр VPN будет отключен для обеспечения базовой функциональности.</string>
<string name="onboarding_network_title">Не ограничивать сеть</string>
<string name="onboarding_network_desc">Data Saving может предотвратить корректную работу TrackerControl в фоновом режиме. Предоставьте неограниченный доступ для наиболее надежной защиты.</string>
<string name="onboarding_network_action">Предоставить неограниченный доступ</string>
Expand Down
6 changes: 0 additions & 6 deletions app/src/main/res/values-sl-rSI/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,6 @@ Vaš internetni promet se ne pošilja na oddaljeni strežnik VPN.</string>
<string name="onboarding_notify_desc">Dovoli obvestila, da si ogledate posodobitve v resničnem času in nadzirate zaščito neposredno iz vrstice stanja.</string>
<string name="onboarding_notify_action">Dovoli obvestila</string>
<string name="onboarding_notify_sure">Brez dovoljenj za obvestila si ne boste mogli ogledati posodobitev v resničnem času ali nadzirati zaščite iz vrstice stanja. Ali ste prepričani?</string>
<string name="onboarding_privatedns_title">Onemogoči zasebni DNS</string>
<string name="onboarding_privatedns_desc">Androidova značilnost \"Zasebni DNS\" moti zmožnost blokiranja sledilcev programa TrackerControl. Če želite nadaljevati, <b>morate</b> to nastavitev izklopiti.</string>
<string name="onboarding_privatedns_instruction">Nastavitve –&gt; Omrežje in internet –&gt; Zasebni DNS –&gt; Izklopi.</string>
<string name="onboarding_privatedns_action">Odpri nastavitve DNS</string>
<string name="onboarding_privatedns_skip_title">Preskoči onemogočanje zasebnega DNS-a?</string>
<string name="onboarding_privatedns_skip_msg">Če nadaljujete z omogočenim zasebnim DNS-om, bo to znatno omejilo TrackerControl. Večina sledenja ne bo blokirana – program bo zmožen samo preučevanja sledilnih knjižnic. Poleg tega bo filter VPN onemogočen, da se zagotovi osnovno delovanje.</string>
<string name="onboarding_timeline_title">Oglejte si, kako se časovnica napolni</string>
<string name="onboarding_timeline_desc">TrackerControl se zažene po časovnici. Na začetku je lahko prazna — programi običajno stopijo v stik s sledilci šele med njihovo uporabo.\n\nKo končate z nastavitvijo odprite nekaj programov in se vrnite v TrackerControl, da si ogledate zaznano in blokirano sledilno dejavnost.</string>
<string name="onboarding_network_title">Neomejeno omrežje</string>
Expand Down
Loading