Files
QSafe/app/src/main/java/ru/kusoft/qsafe/LanPolicy.java
T

36 lines
2.5 KiB
Java

package ru.kusoft.qsafe;
import java.io.IOException;
import java.net.*;
/** Pure validation: never resolves DNS and never opens a socket. */
public final class LanPolicy {
private LanPolicy() {}
public static byte[] ipv4(String text) throws IOException {
if(text==null||!text.matches("[0-9]{1,3}(\\.[0-9]{1,3}){3}"))throw new IOException("Нужен локальный IPv4 Pi, без доменного имени");
String[] parts=text.split("\\.");byte[] out=new byte[4];
for(int i=0;i<4;i++){int value=Integer.parseInt(parts[i]);if(value>255||(parts[i].length()>1&&parts[i].charAt(0)=='0'))throw new IOException("Неверный IPv4");out[i]=(byte)value;}
int a=out[0]&255,b=out[1]&255;
if(!(a==10||a==172&&b>=16&&b<=31||a==192&&b==168))throw new IOException("Внешние адреса базы запрещены. Нужен локальный IPv4 Pi");
return out;
}
public static String url(String address) throws IOException {
try {
URI uri=new URI(address==null?"":address.trim());
if(!"https".equalsIgnoreCase(uri.getScheme())||uri.getHost()==null||uri.getRawUserInfo()!=null||uri.getRawQuery()!=null||uri.getRawFragment()!=null)throw new IOException("Нужен локальный HTTPS-адрес Pi без логина и параметров");
ipv4(uri.getHost());String result=uri.toASCIIString();return result.endsWith("/")?result:result+"/";
}catch(URISyntaxException e){throw new IOException("Неверный адрес Pi",e);}
}
public static void identity(String ssid,String pin)throws IOException {
if(ssid==null||ssid.isEmpty()||ssid.getBytes(java.nio.charset.StandardCharsets.UTF_8).length>32)throw new IOException("Укажите точное имя домашнего Wi-Fi");
if(pin==null||!pin.matches("[0-9a-fA-F]{64}"))throw new IOException("Нужен SHA-256 локального сертификата Pi из файла подключения");
}
public static boolean sameSubnet(byte[] target,byte[] local,int prefix) {
if(target.length!=4||local.length!=4||prefix<16||prefix>30||java.util.Arrays.equals(target,local))return false;
long value=0;for(byte b:target)value=value<<8|(b&255);long hostMask=(1L<<(32-prefix))-1;
if((value&hostMask)==0||(value&hostMask)==hostMask)return false;
for(int i=0;i<4;i++){int bits=Math.max(0,Math.min(8,prefix-i*8));int mask=255<<(8-bits)&255;if((target[i]&mask)!=(local[i]&mask))return false;}
return true;
}
}