diff --git a/util/pom.xml b/util/pom.xml new file mode 100644 index 0000000..1c6672c --- /dev/null +++ b/util/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + de.hsadmin.core + hsadmin-util + 4.0.4-SNAPSHOT + + UTF-8 + 1.8 + 1.8 + + + + junit + junit + 4.13.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + + + diff --git a/util/src/main/java/de/hsadmin/core/util/Config.java b/util/src/main/java/de/hsadmin/core/util/Config.java new file mode 100644 index 0000000..2d713a4 --- /dev/null +++ b/util/src/main/java/de/hsadmin/core/util/Config.java @@ -0,0 +1,58 @@ +package de.hsadmin.core.util; + +import java.io.File; +import java.io.FileReader; +import java.util.Properties; +import java.util.logging.Logger; + +public class Config { + + private static Config instance; + + private static Logger LOG = Logger.getLogger(Config.class.getName()); + + private Properties props; + + private Config() { + props = new Properties(); + File file = new File(System.getProperty("user.dir") + "/hsadmin.properties"); + if (!file.canRead()) { + file = new File(System.getProperty("user.dir") + "/conf/hsadmin.properties"); + } + if (!file.canRead()) { + file = new File(System.getProperty("user.home") + "/.hsadmin.properties"); + } + if (!file.canRead()) { + file = new File("/etc/hsadmin.properties"); + } + if (!file.canRead()) { + file = new File("/etc/hsadmin/hsadmin.properties"); + } + if (file.canRead()) { + try { + LOG.info("Constructor - Properties-File: " + file.getAbsolutePath()); + props.load(new FileReader(file)); + } catch (Exception e) { + // should not happen + e.printStackTrace(); + } + } + } + + public static Config getInstance() { + if (instance == null) { + instance = new Config(); + } + return instance; + } + + public String getProperty(String propertyName) { + String property = props.getProperty(propertyName); + return property; + } + + public String getProperty(String propertyName, String defaultValue) { + return props.getProperty(propertyName, defaultValue).trim(); + } + +} diff --git a/util/src/main/java/de/hsadmin/core/util/HSAdminException.java b/util/src/main/java/de/hsadmin/core/util/HSAdminException.java new file mode 100644 index 0000000..351523c --- /dev/null +++ b/util/src/main/java/de/hsadmin/core/util/HSAdminException.java @@ -0,0 +1,19 @@ +package de.hsadmin.core.util; + +public class HSAdminException extends Exception { + + private static final long serialVersionUID = -5082179267383474532L; + + public HSAdminException(String message) { + super(message); + } + + public HSAdminException(Exception e) { + super(e); + } + + public HSAdminException(String message, Exception aExc) { + super(message, aExc); + } + +} diff --git a/util/src/main/java/de/hsadmin/core/util/IPv6Trick.java b/util/src/main/java/de/hsadmin/core/util/IPv6Trick.java new file mode 100644 index 0000000..bab3fff --- /dev/null +++ b/util/src/main/java/de/hsadmin/core/util/IPv6Trick.java @@ -0,0 +1,86 @@ +package de.hsadmin.core.util; + +import java.net.InetAddress; +import java.net.UnknownHostException; + + +public class IPv6Trick { + + private static final String IPv4_LOCALHOST = "127.0.0"; + private static final String IPv6_LOCALHOST = "::1"; + private static final String IPv6_LOCALHOST_ALT = "0:0:0:0:0:0:0:1"; + + private static final String IPv4_83_223_79 = "83.223.79"; // Alboin-Kontor Berlin + private static final String IPv4_83_223_91 = "83.223.91"; // Alboin-Kontor Berlin + private static final String IPv4_83_223_95 = "83.223.95"; // Alboin-Kontor Berlin + private static final String IPv6_PREFIX_AK = "2a01:37:1000::1"; + + private static final String IPv4_83_223_78 = "83.223.78"; // e-Shelter Berlin + private static final String IPv4_83_223_94 = "83.223.94"; // e-Shelter Berlin + private static final String IPv6_PREFIX_ES = "2a01:37:3000::1"; + + private static final String IPv6_PREFIX_HS = "2a01:37:"; + private static final String IPv6_PREFIX_HS_ALT = "2a01:0037:"; + + public static String convertIPv4ToIPv6(final String ipv4address) throws HSAdminException { + if (ipv4address == null || ipv4address.length() == 0) { + throw new HSAdminException("no IPv4 address given"); + } + try { + InetAddress inetV4Address = InetAddress.getByName(ipv4address); + String inetV4AddressString = inetV4Address.getHostAddress(); + if (inetV4AddressString.startsWith(IPv4_83_223_79) // Alboin-Kontor Berlin + || inetV4AddressString.startsWith(IPv4_83_223_91) + || inetV4AddressString.startsWith(IPv4_83_223_95) ) { + return embedIPv4Address(inetV4Address, InetAddress.getByName(IPv6_PREFIX_AK)); + } + if (inetV4AddressString.startsWith(IPv4_83_223_78) // e-Shelter Berlin + || inetV4AddressString.startsWith(IPv4_83_223_94) ) { + return embedIPv4Address(inetV4Address, InetAddress.getByName(IPv6_PREFIX_ES)); + } + } catch (UnknownHostException e) { + throw new HSAdminException(e); + } + throw new HSAdminException("unknown IPv4 address given"); + } + + public static boolean isKnownRemote(final String remoteAddress) { + boolean isKnown = false; + if (remoteAddress.startsWith(IPv4_LOCALHOST) || remoteAddress.startsWith(IPv6_LOCALHOST) || remoteAddress.startsWith(IPv6_LOCALHOST_ALT)) { + // localhost + isKnown = true; + } + if (remoteAddress.startsWith(IPv6_PREFIX_HS) || remoteAddress.startsWith(IPv6_PREFIX_HS_ALT)) { + // Hostsharing IPv6 + isKnown = true; + } + if (remoteAddress.startsWith(IPv4_83_223_78) || remoteAddress.startsWith(IPv4_83_223_94)) { + // e-Shelter + isKnown = true; + } + if (remoteAddress.startsWith(IPv4_83_223_79) || remoteAddress.startsWith(IPv4_83_223_91) || remoteAddress.startsWith(IPv4_83_223_95)) { + // Speedbone Alboin Kontor + isKnown = true; + } + return isKnown; + } + + private static String embedIPv4Address(final InetAddress ipv4address, final InetAddress ipv6Mask) throws UnknownHostException { + final byte[] ipv4Bytes = ipv4address.getAddress(); + final byte[] ipv6Bytes = ipv6Mask.getAddress(); + ipv6Bytes[10] = ipv4Bytes[0]; + ipv6Bytes[11] = ipv4Bytes[1]; + ipv6Bytes[12] = ipv4Bytes[2]; + ipv6Bytes[13] = ipv4Bytes[3]; + ipv6Bytes[14] = 0; + ipv6Bytes[15] = 0; + final InetAddress ipv6Address = InetAddress.getByAddress(ipv6Bytes); + final String ipv6String = ipv6Address.getHostAddress(); + if (ipv6String.startsWith("/")) { + return ipv6String.substring(1); + } else { + return ipv6String; + } + } + +} diff --git a/util/src/main/java/de/hsadmin/core/util/PasswordGenerator.java b/util/src/main/java/de/hsadmin/core/util/PasswordGenerator.java new file mode 100644 index 0000000..8258cd2 --- /dev/null +++ b/util/src/main/java/de/hsadmin/core/util/PasswordGenerator.java @@ -0,0 +1,147 @@ +package de.hsadmin.core.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public final class PasswordGenerator { + + private static final String LOWER = "abcdefghijklmnopqrstuvwxyz"; + private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private static final String DIGITS = "0123456789"; + private static final String PUNCTUATION = "!@#$%&*()_+-=[]|,./?><"; + private boolean useLower; + private boolean useUpper; + private boolean useDigits; + private boolean usePunctuation; + + private PasswordGenerator() { + throw new UnsupportedOperationException("Empty constructor is not supported."); + } + + private PasswordGenerator(PasswordGeneratorBuilder builder) { + this.useLower = builder.useLower; + this.useUpper = builder.useUpper; + this.useDigits = builder.useDigits; + this.usePunctuation = builder.usePunctuation; + } + + public static class PasswordGeneratorBuilder { + + private boolean useLower; + private boolean useUpper; + private boolean useDigits; + private boolean usePunctuation; + + public PasswordGeneratorBuilder() { + this.useLower = false; + this.useUpper = false; + this.useDigits = false; + this.usePunctuation = false; + } + + /** + * Set true in case you would like to include lower characters (abc...xyz). + * Default false. + * + * @param useLower true in case you would like to include lower characters + * (abc...xyz). Default false. + * @return the builder for chaining. + */ + public PasswordGeneratorBuilder useLower(boolean useLower) { + this.useLower = useLower; + return this; + } + + /** + * Set true in case you would like to include upper characters (ABC...XYZ). + * Default false. + * + * @param useUpper true in case you would like to include upper characters + * (ABC...XYZ). Default false. + * @return the builder for chaining. + */ + public PasswordGeneratorBuilder useUpper(boolean useUpper) { + this.useUpper = useUpper; + return this; + } + + /** + * Set true in case you would like to include digit characters (123..). Default + * false. + * + * @param useDigits true in case you would like to include digit characters + * (123..). Default false. + * @return the builder for chaining. + */ + public PasswordGeneratorBuilder useDigits(boolean useDigits) { + this.useDigits = useDigits; + return this; + } + + /** + * Set true in case you would like to include punctuation characters (!@#..). + * Default false. + * + * @param usePunctuation true in case you would like to include punctuation + * characters (!@#..). Default false. + * @return the builder for chaining. + */ + public PasswordGeneratorBuilder usePunctuation(boolean usePunctuation) { + this.usePunctuation = usePunctuation; + return this; + } + + /** + * Get an object to use. + * + * @return the {@link gr.idrymavmela.business.lib.PasswordGenerator} object. + */ + public PasswordGenerator build() { + return new PasswordGenerator(this); + } + } + + /** + * This method will generate a password depending the use* properties you + * define. It will use the categories with a probability. It is not sure that + * all of the defined categories will be used. + * + * @param length the length of the password you would like to generate. + * @return a password that uses the categories you define when constructing the + * object with a probability. + */ + public String generate(int length) { + // Argument Validation. + if (length <= 0) { + return ""; + } + + // Variables. + StringBuilder password = new StringBuilder(length); + Random random = new Random(System.nanoTime()); + + // Collect the categories to use. + List charCategories = new ArrayList<>(4); + if (useLower) { + charCategories.add(LOWER); + } + if (useUpper) { + charCategories.add(UPPER); + } + if (useDigits) { + charCategories.add(DIGITS); + } + if (usePunctuation) { + charCategories.add(PUNCTUATION); + } + + // Build the password. + for (int i = 0; i < length; i++) { + String charCategory = charCategories.get(random.nextInt(charCategories.size())); + int position = random.nextInt(charCategory.length()); + password.append(charCategory.charAt(position)); + } + return new String(password); + } +} \ No newline at end of file diff --git a/util/src/main/java/de/hsadmin/core/util/PasswordTool.java b/util/src/main/java/de/hsadmin/core/util/PasswordTool.java new file mode 100644 index 0000000..9f87743 --- /dev/null +++ b/util/src/main/java/de/hsadmin/core/util/PasswordTool.java @@ -0,0 +1,44 @@ +package de.hsadmin.core.util; + +public final class PasswordTool { + + public static final int MIN_COMPLEXITY = 3; + public static final int MIN_PASSWORD_LENGTH = 6; + + private static final PasswordGenerator passwordGenerator = new PasswordGenerator.PasswordGeneratorBuilder() + .useDigits(true) + .useLower(true) + .useUpper(true) + .build(); + + public static String generatePassword() { + return passwordGenerator.generate(14); + } + + public static void checkPasswordComplexity(final String password) throws HSAdminException { + int containsLowercaseCharacter = 0; + int containsUppercaseCharacter = 0; + int containsSpecialCharacter = 0; + int containsDigit = 0; + for (int idx = 0; idx < password.length(); idx++) { + char chr = password.charAt(idx); + if (chr >= 'a' && chr <= 'z') { + containsLowercaseCharacter = 1; + } else + if (chr >= 'A' && chr <= 'Z') { + containsUppercaseCharacter = 1; + } else + if (chr >= '0' && chr <= '1') { + containsDigit = 1; + } else { + containsSpecialCharacter = 1; + } + } + int complexity = containsLowercaseCharacter + containsUppercaseCharacter + + containsSpecialCharacter + containsDigit; + if (complexity < MIN_COMPLEXITY || password.length() < MIN_PASSWORD_LENGTH) { + throw new HSAdminException("simple password"); + } + } + +} diff --git a/util/src/main/java/de/hsadmin/core/util/TextUtil.java b/util/src/main/java/de/hsadmin/core/util/TextUtil.java new file mode 100644 index 0000000..1c80168 --- /dev/null +++ b/util/src/main/java/de/hsadmin/core/util/TextUtil.java @@ -0,0 +1,87 @@ +package de.hsadmin.core.util; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +public class TextUtil { + + private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN); + + public static synchronized String replaceUmlautCharacters(String umlautString) { + StringBuffer buffer = new StringBuffer(); + for (char c : umlautString.toCharArray()) { + if ( (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + (c == ' ') ) { + buffer.append(c); + } else { + switch (c) { + case 'ä': + buffer.append("ae"); + break; + case 'ö': + buffer.append("oe"); + break; + case 'ü': + buffer.append("ue"); + break; + case 'Ä': + buffer.append("Ae"); + break; + case 'Ö': + buffer.append("Oe"); + break; + case 'Ü': + buffer.append("Ue"); + break; + case 'ß': + buffer.append("ss"); + break; + default: + buffer.append('-'); + break; + } + } + } + return buffer.toString(); + } + + public static synchronized String format(Date date) { + return df.format(date); + } + + public static synchronized Date parseDate(String dateString) { + try { + return df.parse(dateString); + } catch (ParseException e) { + try { + return df.parse("01.01.1970"); + } catch (ParseException e1) { + // don't care + return null; + } + } + } + + public static synchronized String format(boolean free) { + return free ? "true" : "false"; + } + + public static synchronized boolean parseBool(String boolString) { + boolean parsedValue = "T".equals(boolString.toUpperCase()) || "TRUE".equals(boolString.toUpperCase()); + return parsedValue; + } + + public static synchronized String hidePassword(String passwd) { + final StringBuffer val = new StringBuffer(passwd.substring(0, 2)); + for (int i = 2; i < 6; i++) { + val.append('*'); + } + return val.toString(); + } + +} diff --git a/util/src/test/java/de/hsadmin/core/util/IPv6TrickTest.java b/util/src/test/java/de/hsadmin/core/util/IPv6TrickTest.java new file mode 100644 index 0000000..7d17a8f --- /dev/null +++ b/util/src/test/java/de/hsadmin/core/util/IPv6TrickTest.java @@ -0,0 +1,39 @@ +package de.hsadmin.core.util; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Test; + +public class IPv6TrickTest { + + @After + public void tearDown() throws Exception { + } + + @Test + public void testConvertIPv4ToIPv6() { + try { + assertTrue(IPv6Trick.convertIPv4ToIPv6("83.223.78.2").startsWith("2a01:37:")); + assertTrue(IPv6Trick.convertIPv4ToIPv6("83.223.79.22").startsWith("2a01:37:")); + assertTrue(IPv6Trick.convertIPv4ToIPv6("83.223.91.222").startsWith("2a01:37:")); + assertTrue(IPv6Trick.convertIPv4ToIPv6("83.223.94.2").startsWith("2a01:37:")); + assertTrue(IPv6Trick.convertIPv4ToIPv6("83.223.95.2").startsWith("2a01:37:")); + } catch (HSAdminException e) { + fail(e.getMessage()); + } + try { + IPv6Trick.convertIPv4ToIPv6("4.4.4.4"); + fail("unknown adress"); + } catch (HSAdminException e) { + // Ok + } + } + + @Test + public void testIsKnownRemote() { + assertTrue(IPv6Trick.isKnownRemote("83.223.78.2")); + } + +} diff --git a/util/src/test/java/de/hsadmin/core/util/PasswordToolTest.java b/util/src/test/java/de/hsadmin/core/util/PasswordToolTest.java new file mode 100644 index 0000000..1e586f5 --- /dev/null +++ b/util/src/test/java/de/hsadmin/core/util/PasswordToolTest.java @@ -0,0 +1,62 @@ +package de.hsadmin.core.util; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class PasswordToolTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testCheckPasswordComplexity() { + String pw1 = "TTtt1"; + String pw2 = "TTtt11"; + String pw3 = "TTT12_"; + String pw4 = "Testt1"; + String pw5 = "Tthdsuhdalkdj"; + String pw6 = "zaehler42"; + try { + PasswordTool.checkPasswordComplexity(pw1); + fail("should fail"); + } catch (HSAdminException e) { + assertTrue("simple password".equals(e.getMessage())); + } + try { + PasswordTool.checkPasswordComplexity(pw2); + } catch (HSAdminException e) { + fail(e.getMessage()); + } + try { + PasswordTool.checkPasswordComplexity(pw3); + } catch (HSAdminException e) { + fail(e.getMessage()); + } + try { + PasswordTool.checkPasswordComplexity(pw4); + } catch (HSAdminException e) { + fail(e.getMessage()); + } + try { + PasswordTool.checkPasswordComplexity(pw5); + fail("should fail"); + } catch (HSAdminException e) { + assertTrue("simple password".equals(e.getMessage())); + } + try { + PasswordTool.checkPasswordComplexity(pw6); + fail("should fail"); + } catch (HSAdminException e) { + assertTrue("simple password".equals(e.getMessage())); + } + } + +}