package ganarchy.friendcode.sam; import ganarchy.friendcode.util.ConfigUtil; import org.apache.commons.codec.binary.Base32; import java.security.SecureRandom; import java.util.Properties; /** * Helper for I2P SAM authentication. */ public class I2PSamAuthUtil { /** * The default username. It is used by default. */ private static final String DEFAULT_USERNAME = "minecraft_friendcode"; /** * Fallback authentication password, used on first install. */ private static final AuthenticationPair INSECURE_FALLBACK = new AuthenticationPair(DEFAULT_USERNAME, "friendcode"); /** * Returns the currently active SAM auth pair. */ public static AuthenticationPair getAuthPair() { AuthenticationPair strongAuthPair = getStrongAuthPair(); if (strongAuthPair != null) { return strongAuthPair; } return INSECURE_FALLBACK; } /** * Generates and stores a modern auth pair. * * @return The generated auth pair. */ public static AuthenticationPair upgradeAuthPair() { var rand = new SecureRandom(); var bytes = new byte[16]; rand.nextBytes(bytes); var b32 = new Base32().encodeToString(bytes); Properties auth = new Properties(); auth.setProperty("i2p.sam.username", DEFAULT_USERNAME); auth.setProperty("i2p.sam.password", b32); if (ConfigUtil.updateSettings(auth)) { return new AuthenticationPair(DEFAULT_USERNAME, b32); } else { return INSECURE_FALLBACK; } } /** * Returns whether strong auth is enabled. */ public static boolean isStrongAuth() { return getStrongAuthPair() != null; } /** * Returns the currently active strong SAM auth pair, or null if using the * weak fallback. */ private static AuthenticationPair getStrongAuthPair() { Properties auth = new Properties(); if (ConfigUtil.getSettings(auth)) { String username = auth.getProperty("i2p.sam.username"); String password = auth.getProperty("i2p.sam.password"); if (username != null && password != null) { return new AuthenticationPair(username, password); } } return null; } /** * An authentication pair. * * @param user The username. * @param password The password. */ public record AuthenticationPair(String user, String password) { } }