commit 5235a586551be2e0671b9d7a3a53214061084abc Author: Michal Date: Thu May 23 15:23:35 2024 +0200 import diff --git a/TODO b/TODO new file mode 100644 index 0000000..c0cf5e5 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ ++ pridavani typu zarizení vcetne ikon + ++ ruzne type objektu + obecny objekt s zadnou funkcí + odkaz na jinou mapu + zarizeni site + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..0772a7b --- /dev/null +++ b/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project JGuardServer. + + + diff --git a/config b/config new file mode 100644 index 0000000..6a4efb6 --- /dev/null +++ b/config @@ -0,0 +1,15 @@ +#Sat Jan 19 23:43:37 CET 2019 +mysql_server=89.103.77.58 +mysql_port=18000 +#mysql_server=10.10.0.51 +#mysql_port=3306 +mysql_user=root +mysql_password=Michal2407 +mysql_database=jGuard +server_port=1225 +client_version=25 +debug=false + +interface_mac=30-52-CB-20-B2-6F +gateway_mac=D0-96-FB-43-CE-1F +#D4-CA-6D-21-F1-6F diff --git a/img/add.png b/img/add.png new file mode 100644 index 0000000..4a5bf9f Binary files /dev/null and b/img/add.png differ diff --git a/img/app.png b/img/app.png new file mode 100644 index 0000000..8de69c3 Binary files /dev/null and b/img/app.png differ diff --git a/img/arrow.png b/img/arrow.png new file mode 100644 index 0000000..2af7b7f Binary files /dev/null and b/img/arrow.png differ diff --git a/img/browser.png b/img/browser.png new file mode 100644 index 0000000..32829c6 Binary files /dev/null and b/img/browser.png differ diff --git a/img/connect.png b/img/connect.png new file mode 100644 index 0000000..5c8e6e3 Binary files /dev/null and b/img/connect.png differ diff --git a/img/cursor_connection.png b/img/cursor_connection.png new file mode 100644 index 0000000..6492f7f Binary files /dev/null and b/img/cursor_connection.png differ diff --git a/img/device/dasan_olt.png b/img/device/dasan_olt.png new file mode 100644 index 0000000..781e884 Binary files /dev/null and b/img/device/dasan_olt.png differ diff --git a/img/device/dasan_ont.png b/img/device/dasan_ont.png new file mode 100644 index 0000000..4867aef Binary files /dev/null and b/img/device/dasan_ont.png differ diff --git a/img/device/mikrotik.png b/img/device/mikrotik.png new file mode 100644 index 0000000..3c05f5f Binary files /dev/null and b/img/device/mikrotik.png differ diff --git a/img/device/racom_ray.png b/img/device/racom_ray.png new file mode 100644 index 0000000..9f22ec7 Binary files /dev/null and b/img/device/racom_ray.png differ diff --git a/img/device/racom_ray_2.png b/img/device/racom_ray_2.png new file mode 100644 index 0000000..46eec0a Binary files /dev/null and b/img/device/racom_ray_2.png differ diff --git a/img/device/summit_bt.png b/img/device/summit_bt.png new file mode 100644 index 0000000..d36547f Binary files /dev/null and b/img/device/summit_bt.png differ diff --git a/img/device/summit_sdv.png b/img/device/summit_sdv.png new file mode 100644 index 0000000..bb0b3ab Binary files /dev/null and b/img/device/summit_sdv.png differ diff --git a/img/device/sw_hp.png b/img/device/sw_hp.png new file mode 100644 index 0000000..a2d74d2 Binary files /dev/null and b/img/device/sw_hp.png differ diff --git a/img/device/sw_tp_link.png b/img/device/sw_tp_link.png new file mode 100644 index 0000000..76879b2 Binary files /dev/null and b/img/device/sw_tp_link.png differ diff --git a/img/device/tinycontrol.png b/img/device/tinycontrol.png new file mode 100644 index 0000000..077a2af Binary files /dev/null and b/img/device/tinycontrol.png differ diff --git a/img/device/ubnt.png b/img/device/ubnt.png new file mode 100644 index 0000000..94ad4fa Binary files /dev/null and b/img/device/ubnt.png differ diff --git a/img/flag_gray.png b/img/flag_gray.png new file mode 100644 index 0000000..a7e38db Binary files /dev/null and b/img/flag_gray.png differ diff --git a/img/flag_green.png b/img/flag_green.png new file mode 100644 index 0000000..def17cc Binary files /dev/null and b/img/flag_green.png differ diff --git a/img/flag_orange.png b/img/flag_orange.png new file mode 100644 index 0000000..edd3cef Binary files /dev/null and b/img/flag_orange.png differ diff --git a/img/flag_red.png b/img/flag_red.png new file mode 100644 index 0000000..e99a587 Binary files /dev/null and b/img/flag_red.png differ diff --git a/img/lock.png b/img/lock.png new file mode 100644 index 0000000..67bb215 Binary files /dev/null and b/img/lock.png differ diff --git a/img/log.png b/img/log.png new file mode 100644 index 0000000..7d60021 Binary files /dev/null and b/img/log.png differ diff --git a/img/online_clients.png b/img/online_clients.png new file mode 100644 index 0000000..becc247 Binary files /dev/null and b/img/online_clients.png differ diff --git a/img/ping.png b/img/ping.png new file mode 100644 index 0000000..97f86be Binary files /dev/null and b/img/ping.png differ diff --git a/img/platform_android.png b/img/platform_android.png new file mode 100644 index 0000000..3347635 Binary files /dev/null and b/img/platform_android.png differ diff --git a/img/platform_pc.png b/img/platform_pc.png new file mode 100644 index 0000000..f5bad40 Binary files /dev/null and b/img/platform_pc.png differ diff --git a/img/server.png b/img/server.png new file mode 100644 index 0000000..ab747f7 Binary files /dev/null and b/img/server.png differ diff --git a/img/settings.png b/img/settings.png new file mode 100644 index 0000000..f45c23f Binary files /dev/null and b/img/settings.png differ diff --git a/img/ssh.png b/img/ssh.png new file mode 100644 index 0000000..d35b274 Binary files /dev/null and b/img/ssh.png differ diff --git a/img/trash.png b/img/trash.png new file mode 100644 index 0000000..0e634f4 Binary files /dev/null and b/img/trash.png differ diff --git a/img/unlock.png b/img/unlock.png new file mode 100644 index 0000000..fdcb342 Binary files /dev/null and b/img/unlock.png differ diff --git a/img/winbox.png b/img/winbox.png new file mode 100644 index 0000000..492d23e Binary files /dev/null and b/img/winbox.png differ diff --git a/log.txt b/log.txt new file mode 100644 index 0000000..716a009 --- /dev/null +++ b/log.txt @@ -0,0 +1,39 @@ +01.11.20 18:28:27 I ------------------------- +01.11.20 18:28:27 I jGuard Server +01.11.20 18:28:27 I ------------------------- +01.11.20 18:28:27 I Version: 1 (Sun Oct 25 16:22:20 CET 2020) +01.11.20 18:28:27 I OS detect ... +01.11.20 18:28:27 I windows +01.11.20 18:28:27 I Loading config ... +01.11.20 18:28:27 I successfully +01.11.20 18:28:27 I Connecting to a selected database ... +01.11.20 18:28:29 I successfully +01.11.20 18:28:29 I Loading map and object list ... +01.11.20 18:28:33 I load 5 maps +01.11.20 18:28:33 I Probe thread run +01.11.20 18:28:33 D 7 network interface available +01.11.20 18:28:33 I Local adress: 192.168.122.107 +01.11.20 18:28:33 D Capture Thread run +01.11.20 18:28:34 I Server started on port 1225 +01.11.20 18:28:36 I Pozadavek na autorizaci odeslan (127.0.0.1) +01.11.20 18:28:37 I Uživatel: michal přihlášen (127.0.0.1) +01.11.20 18:28:38 I Spusten ping na: 10.10.0.2 +01.11.20 18:28:38 I Spusten ping na: 89.103.77.58 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.51 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.47 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.4 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.41 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.54 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.50 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.40 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.16 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.3 +01.11.20 18:28:38 I Spusten ping na: 10.0.60.195 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.42 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.54 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.147 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.30 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.17 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.10 +01.11.20 18:28:38 I Spusten ping na: 10.0.0.31 +01.11.20 18:28:38 I Spusten ping na: 10.10.0.52 diff --git a/manifest.mf b/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..bcb9eda --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..83606af --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=24a327c4 +build.xml.script.CRC32=4e5395cd +build.xml.stylesheet.CRC32=8064a381@1.80.1.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=24a327c4 +nbproject/build-impl.xml.script.CRC32=a4c12d70 +nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48 diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..2be9c08 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,83 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=JGuardServer +application.vendor=Michal +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/JGuardServer.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.mysql-connector-java-8.0.15.jar=C:\\Users\\Michal\\Documents\\NetBeansProjects\\JAR lib\\mysql-connector-java-8.0.15.jar +file.reference.netty-all-4.1.33.Final.jar=C:\\Users\\Michal\\Documents\\NetBeansProjects\\JAR lib\\netty-all-4.1.33.Final.jar +includes=** +jar.compress=false +javac.classpath=\ + ${reference.jGuard.jar}:\ + ${file.reference.netty-all-4.1.33.Final.jar}:\ + ${file.reference.mysql-connector-java-8.0.15.jar} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=true +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=cucky.jguard.server.Main +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.jGuard=../jGuard +reference.jGuard.jar=${project.jGuard}/dist/jGuard.jar +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..cdee5ef --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,25 @@ + + + org.netbeans.modules.java.j2seproject + + + JGuardServer + + + + + + + + + + jGuard + jar + + jar + clean + jar + + + + diff --git a/src/cucky/jguard/server/Config.java b/src/cucky/jguard/server/Config.java new file mode 100644 index 0000000..2a51516 --- /dev/null +++ b/src/cucky/jguard/server/Config.java @@ -0,0 +1,134 @@ +package cucky.jguard.server; + +import cucky.jGuard.lib.LogFile; +import cucky.jGuard.lib.OSValidator; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +public class Config { + + private Properties prop = new Properties(); + private String configFile = "config"; + private OutputStream output = null; + private InputStream input = null; + + public static Map conf = new HashMap(); + + public Config() { + + } + + private InputStream getFile(String configFile) throws Exception{ + if (OSValidator.isWindows()) { + return new FileInputStream(configFile); + } else if (OSValidator.isUnix()) { + return new FileInputStream("/jGuardServer/"+configFile); + } + return null; + } + + public String get(String name) { + + try { + + input = getFile(configFile); + + // load a properties file + prop.load(input); + + return prop.getProperty(name); + + } catch (Exception ex) { + LogFile.printErr("Config file exception: " + ex.getLocalizedMessage()); + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + LogFile.printErr("Config file exception: " + e.getLocalizedMessage()); + } + } + } + return ""; + } + + public void set(String name, String value) { + try { + + output = new FileOutputStream(configFile); + + // set the properties value + prop.setProperty(name, value); + + // save properties to project root folder + prop.store(output, null); + + } catch (IOException io) { + LogFile.printErr("Config file exception: " + io.getLocalizedMessage()); + } finally { + if (output != null) { + try { + output.close(); + } catch (IOException e) { + LogFile.printErr("Config file exception: " + e.getLocalizedMessage()); + } + } + } + } + + public Properties loadAll(){ + try { + + input = getFile(configFile); + + if (input == null) { + LogFile.printErr("Config file error: input is null"); + return null; + } + prop.load(input); + + return prop; + } catch (Exception ex) { + LogFile.printErr("Config file exception1: " + ex.getMessage()); + return null; + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + LogFile.printErr("Config file exception: " + e.getLocalizedMessage()); + } + } + } + } + + public void store(Properties prop){ + try { + + output = new FileOutputStream(configFile); + + // save properties to project root folder + prop.store(output, null); + + } catch (IOException io) { + LogFile.printErr("Config file exception: " + io.getLocalizedMessage()); + } finally { + if (output != null) { + try { + output.close(); + } catch (IOException e) { + LogFile.printErr("Config file exception: " + e.getLocalizedMessage()); + } + } + + } + } + +} diff --git a/src/cucky/jguard/server/Database.java b/src/cucky/jguard/server/Database.java new file mode 100644 index 0000000..001ab82 --- /dev/null +++ b/src/cucky/jguard/server/Database.java @@ -0,0 +1,547 @@ +package cucky.jguard.server; + +import cucky.jGuard.lib.LogFile; +import cucky.jGuard.lib.object.ObjectType; +import cucky.jGuard.lib.object.Map; +import cucky.jGuard.lib.object.MapObject; +import cucky.jGuard.lib.object.ObjectConnection; +import cucky.jGuard.lib.object.ObjectServices; +import cucky.jGuard.lib.object.ServerSettings; +import cucky.jGuard.lib.object.SnmpProbe; +import cucky.jGuard.lib.object.SnmpProfile; +import cucky.jGuard.lib.object.User; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; + +public class Database { + + private static Connection connection = null; + private static String host; + private static String port; + private static String database; + private static String user; + private static String password; + + + public void connect(String host, String port, String database, String user, String password) { + this.host = host; + this.port = port; + this.database = database; + this.user = user; + this.password = password; + + connection = connect(); + } + + private static Connection connect() { + try { + LogFile.printInfo("Connecting to a selected database ..."); + Connection connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "" + + "?useUnicode=true" + + "&characterEncoding=UTF-8" + + "&autoReconnect=true" + + "&serverTimezone=UTC", user, password); + LogFile.printInfo(" successfully"); + return connection; + } catch (SQLException ex) { + LogFile.printErr("MySQL connection exception: " + ex.getMessage()); + System.exit(0); + } + return null; + } + + /** + * vrati aktualni spojeni + * @return + * @throws SQLException + */ + public static Connection getCurrentConnection() throws SQLException { + if (connection != null || connection.isClosed()) { + return connection; + } else { + connection = connect(); + } + return null; + } + + /** + * obecny dotaz + * @param sqlQuery + */ + public static void query(String sqlQuery) { + try { + Statement statement = getCurrentConnection().createStatement(); + statement.executeUpdate(sqlQuery); + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage()); + } + } + + /** + * insert + * @param sql dotaz + * @return pri uspesnem vlozeni vrati posledni vlozeny id + */ + public static int insert(String sqlQuery) { + long id = -1; + try { + Statement statement = getCurrentConnection().createStatement(); + statement.executeUpdate(sqlQuery, Statement.RETURN_GENERATED_KEYS); + + PreparedStatement getLastInsertId = getCurrentConnection().prepareStatement("SELECT LAST_INSERT_ID()"); + ResultSet rs = getLastInsertId.executeQuery(); + if (rs.next()) { + id = rs.getLong("last_insert_id()"); + } + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage() + " SQL: " + sqlQuery); + } + return (int) id; + } + + /** + * update + * @param sql sql dotaz + */ + public static void update(String sql) { + try { + Statement statement = getCurrentConnection().createStatement(); + statement.executeUpdate(sql); + statement.close(); + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage() + " SQL: " + sql); + } + } + + /** + * overi zda se v databazi nachazi uzivatel s odpovidajicim heslem + * @param username + * @param password + * @return + */ + public static boolean verifyUser(String username, String password) { + try { + String sql = "SELECT count(*) FROM users WHERE username = '" + username + "' && password = '" + password + "'"; + Statement statement = getCurrentConnection().createStatement(); + ResultSet rs = statement.executeQuery(sql); + rs.next(); + int rowCount = rs.getInt(1); + rs.close(); + if (rowCount == 1) { + return true; + } + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage()); + } + return false; + } + + /** + * vráti seznam vsech map + * @return ArrayList + */ + public static ArrayList getMapList() { + String sql = "SELECT * FROM maps"; + ArrayList list = new ArrayList(); + try { + Statement statement = getCurrentConnection().createStatement(); + ResultSet rs = statement.executeQuery(sql); + while (rs.next()) { + list.add(new Map( + rs.getInt("id"), + rs.getString("name"), + rs.getBoolean("locked"), + getMapObject(rs.getInt("id")), + getObjectConnection(rs.getInt("id")) + )); + } + rs.close(); + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql); + } + return list; + } + + /** + * vrati seznam objektu odpovidajici mape + * @param mapId id mapy + * @return ArrayList + */ + public static ArrayList getMapObject(int mapId) { + ArrayList list = new ArrayList<>(); + String sql = "SELECT * FROM object WHERE map_id = " + mapId; + try { + Statement statement = getCurrentConnection().createStatement(); + ResultSet r = statement.executeQuery(sql); + while (r.next()) { + ObjectServices service = new ObjectServices( + r.getBoolean("winbox"), + r.getString("portWinbox"), + r.getBoolean("ssh"), + r.getString("portSsh"), + r.getBoolean("web"), + r.getString("portWeb"), + r.getInt("verzeWeb"), + r.getBoolean("telnet"), + r.getString("portTelnet"), + r.getBoolean("sms"), + r.getString("portSms"), + r.getInt("verzeSms") + ); + + list.add(new MapObject( + r.getInt("id"), + mapId, + r.getString("name"), + r.getInt("type"), + r.getInt("x"), + r.getInt("y"), + r.getString("ip"), + r.getString("user"), + r.getString("password"), + r.getBoolean("active"), + r.getBoolean("notification_sms"), + r.getBoolean("notification_sound"), + service, + r.getString("location"), + r.getString("description"), + r.getInt("snmpProfile"), + getSnmpProbe(r.getInt("id")) + )); + } + r.close(); + statement.close(); + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql); + } + return list; + } + + /** + * vrati seznam propojeni na zaklade mapy + * @param mapId + * @return + */ + private static ArrayList getObjectConnection(int mapId) { + ArrayList list = new ArrayList(); + try { + String sql = "SELECT * FROM objectConnection WHERE map_id = " + mapId; + Statement statement = getCurrentConnection().createStatement(); + ResultSet r_con = statement.executeQuery(sql); + while (r_con.next()) { + list.add(new ObjectConnection( + r_con.getInt("id"), + r_con.getInt("from_obj"), + r_con.getInt("to_obj"), + r_con.getInt("type"), + r_con.getBoolean("snmp_read"), + r_con.getInt("sourceObjectId"), + r_con.getInt("iface") + )); + } + r_con.close(); + } catch (SQLException ex) { + System.out.println("MySQL exception: " + ex.getMessage()); + } + return list; + } +/* + private static ArrayList getSnmpProbe(int objId) { + ArrayList list = new ArrayList(); + try { + String sql = "SELECT * FROM snmpProbe WHERE mapObject = " + objId; + Statement statement = getCurrentConnection().createStatement(); + ResultSet r_con = statement.executeQuery(sql); + while (r_con.next()) { + list.add(new SnmpProbe( + r_con.getInt("id"), + r_con.getString("desc"), + r_con.getString("oid"), + r_con.getBoolean("view") + )); + } + r_con.close(); + } catch (SQLException ex) { + System.out.println("MySQL exception: " + ex.getMessage()); + } + return list; + } + */ + + /** + * vrati informace o uzivateli podle jmena + * @param username + * @return User + */ + static User getUserInfo(String username) { + User u = null; + try { + Statement statement = getCurrentConnection().createStatement(); + ResultSet r_con = statement.executeQuery("SELECT * FROM users WHERE username = '" + username + "'"); + while (r_con.next()) { + u = new User(r_con.getInt("id"), + username, + r_con.getBoolean("setServer"), + r_con.getBoolean("addMap"), + r_con.getBoolean("removeMap"), + r_con.getBoolean("addObject"), + r_con.getBoolean("removeObject"), + r_con.getBoolean("disableObject")); + } + r_con.close(); + } catch (SQLException ex) { + LogFile.printErr("MySQL exception: " + ex.getMessage()); + } + return u; + } + + /** + * vrati nastaveni serveru + * @return ServerSettings + */ + static ServerSettings getServerSettings() { + ArrayList snmp = new ArrayList<>(); + ArrayList user = new ArrayList<>(); + try { + Statement statement = getCurrentConnection().createStatement(); + ResultSet rs = statement.executeQuery("SELECT * FROM snmpProfile"); + while (rs.next()) { + snmp.add(new SnmpProfile( + rs.getInt("id"), + rs.getString("name"), + rs.getInt("version"), + rs.getString("port"), + rs.getString("community") + )); + } + rs.close(); + ResultSet su = statement.executeQuery("SELECT * FROM users"); + while (su.next()) { + user.add(new User( + su.getInt("id"), + su.getString("username"), + su.getBoolean("setServer"), + su.getBoolean("addMap"), + su.getBoolean("removeMap"), + su.getBoolean("addObject"), + su.getBoolean("removeObject"), + su.getBoolean("disableObject") + )); + } + rs.close(); + } catch (SQLException ex) { + System.out.println("MySQL exception: " + ex.getMessage()); + } + + return new ServerSettings(snmp, user); + } + + /** + * vrati seznam SNMP sond podle objektu + * @param objId + * @return + */ + private static ArrayList getSnmpProbe(int objId) { + ArrayList list = new ArrayList(); + try { + String sql = "SELECT * FROM snmpProbe WHERE mapObject = " + objId; + Statement statement = getCurrentConnection().createStatement(); + ResultSet r_con = statement.executeQuery(sql); + while (r_con.next()) { + list.add(new SnmpProbe( + r_con.getInt("id"), + r_con.getString("desc"), + r_con.getString("oid"), + r_con.getBoolean("view") + )); + } + r_con.close(); + } catch (SQLException ex) { + System.out.println("MySQL exception: " + ex.getMessage()); + } + return list; + } + + /** + * vklada typ zarizeni do databaze + * @param name nazev + * @param img_str obrazek v textove podobe + */ + public static int addDeviceType(String name, String img_str) { + String sql = "INSERT INTO object_type (name, img_str) VALUES('" + name + "', '" + img_str + "')"; + long id = -1; + try { + Statement statement = getCurrentConnection().createStatement(); + statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); + + PreparedStatement getLastInsertId = getCurrentConnection().prepareStatement("SELECT LAST_INSERT_ID()"); + ResultSet rs = getLastInsertId.executeQuery(); + if (rs.next()) { + id = rs.getLong("last_insert_id()"); + } + } catch (SQLException ex) { + LogFile.printErr("Exception add device type: " + ex.getMessage()); + } + return (int) id; + } + + /** + * prida propojeni dvou objektu + * @param ObjectConnection + * @return + */ + public static int addObjectConnection(ObjectConnection c) { + String sql = "INSERT INTO objectConnection (" + + "map_id, " + + "from_obj, " + + "to_obj, " + + "type, " + + "snmp_read," + + "sourceObjectId, " + + "iface" + + ") VALUES(" + + "'" + c.getMap() + "', " + + "'" + c.getFrom() + "', " + + "'" + c.getTo() + "', " + + "'" + c.getType() + "', " + + "'" + (c.isRead()? "1" : "0") + "', " + + "'" + c.getSourceObjectId() + "', " + + "'" + c.getIface() + "'" + + ")"; + long id = -1; + try { + Statement statement = getCurrentConnection().createStatement(); + statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); + + PreparedStatement getLastInsertId = getCurrentConnection().prepareStatement("SELECT LAST_INSERT_ID()"); + ResultSet rs = getLastInsertId.executeQuery(); + if (rs.next()) { + id = rs.getLong("last_insert_id()"); + } + } catch (SQLException ex) { + LogFile.printErr("Exception add device type: " + ex.getMessage() + "(SQL: " + sql + ")"); + } + return (int) id; + } + + /** + * vraci seznam typu zarizeni nacteny z databaze + * @return + */ + public static ArrayList listObjectType(){ + ArrayList dt = new ArrayList<>(); + try { + String sql = "SELECT * FROM object_type"; + Statement statement = getCurrentConnection().createStatement(); + ResultSet r_con = statement.executeQuery(sql); + while (r_con.next()) { + dt.add(new ObjectType(r_con.getInt("id"), r_con.getString("name"), r_con.getString("img_str"))); + } + r_con.close(); + } catch (SQLException ex) { + LogFile.printErr("MySQL exception list device type: " + ex.getMessage()); + } + return dt; + } + + /** + * prida map object + * @param mo + */ + public static int addObject(MapObject mo) { + int id = -1; + String query = "INSERT INTO object (" + + "name, " + + "ip, " + + "type, " + + "user, " + + "password, " + + "snmpProfile, " + + "winbox, " + + "portWinbox, " + + "ssh, " + + "portSsh, " + + "web, " + + "portWeb, " + + "verzeWeb, " + + "telnet, " + + "portTelnet, " + + "sms, " + + "portSms, " + + "verzeSms, " + + "map_id, " + + "x, " + + "y, " + + "active, " + + "description, " + + "location" + + ") VALUES (" + + "'" + mo.getName() + "', " + + "'" + mo.getIp() + "', " + + "'" + mo.getType() + "', " + + "'" + mo.getUser() + "', " + + "'" + mo.getPassword() + "', " + + "'" + mo.getSnmpProfile() + "', " + + "'" + (mo.getService().isWinbox() ? "1" : "0") + "', " + + "'" + mo.getService().getPortWinbox() + "', " + + "'" + (mo.getService().isSsh()? "1" : "0") + "', " + + "'" + mo.getService().getPortSsh() + "', " + + "'" + (mo.getService().isWeb()? "1" : "0") + "', " + + "'" + mo.getService().getPortWeb() + "', " + + "'" + mo.getService().getVerzeWeb() + "', " + + "'" + (mo.getService().isTelnet()? "1" : "0") + "', " + + "'" + mo.getService().getPortTelnet() + "', " + + "'" + (mo.getService().isSms()? "1" : "0") + "', " + + "'" + mo.getService().getPortSms() + "', " + + "'" + mo.getService().getVerzeSms() + "', " + + "'" + mo.getMap() + "', " + + "'" + mo.getX() + "', " + + "'" + mo.getY() + "'," + + "'" + (mo.isActive()? "1" : "0") + "', " + + "'" + mo.getDescription() + "', " + + "'" + mo.getLocation() + "'" + + ")"; + id = insert(query); + return id; + } + + /** + * aktualizuje objekt + * @param mo MapObject + */ + static void updateObject(MapObject mo) { + String sql = "UPDATE object SET " + + "name = '" + mo.getName() + "', " + + "ip = '" + mo.getIp() + "', " + + "type = '" + mo.getType() + "', " + + "user = '" + mo.getUser() + "', " + + "password = '" + mo.getPassword() + "', " + + "snmpProfile = '" + mo.getSnmpProfile() + "', " + + "winbox = '" + (mo.getService().isWinbox() ? "1" : "0") + "', " + + "portWinbox = '" + mo.getService().getPortWinbox() + "', " + + "ssh = '" + (mo.getService().isSsh()? "1" : "0") + "', " + + "portSsh = '" + mo.getService().getPortSsh() + "', " + + "web = '" + (mo.getService().isWeb()? "1" : "0") + "', " + + "portWeb = '" + mo.getService().getPortWeb() + "', " + + "verzeWeb = '" + mo.getService().getVerzeWeb() + "', " + + "telnet = '" + (mo.getService().isTelnet()? "1" : "0") + "', " + + "portTelnet = '" + mo.getService().getPortTelnet() + "', " + + "sms = '" + (mo.getService().isSms()? "1" : "0") + "', " + + "portSms = '" + mo.getService().getPortSms() + "', " + + "verzeSms = '" + mo.getService().getVerzeSms() + "', " + + "map_id = '" + mo.getMap() + "', " + + "x = '" + mo.getX() + "', " + + "y = '" + mo.getY() + "', " + + "active = '" + (mo.isActive()? "1" : "0") + "', " + + "description = '" + mo.getDescription() + "', " + + "location = '" + mo.getLocation() + "'" + + "WHERE id = " + mo.getId(); + update(sql); + } + +} diff --git a/src/cucky/jguard/server/Main.java b/src/cucky/jguard/server/Main.java new file mode 100644 index 0000000..d7bb299 --- /dev/null +++ b/src/cucky/jguard/server/Main.java @@ -0,0 +1,96 @@ +package cucky.jguard.server; + +import cucky.jGuard.lib.BuilddDate; +import cucky.jGuard.lib.LogFile; +import cucky.jGuard.lib.OSValidator; +import cucky.jGuard.lib.object.Map; +import cucky.jGuard.lib.object.MapObject; +import cucky.jGuard.lib.object.OnlineClients; +import java.util.ArrayList; +import java.util.Properties; +import cucky.jquard.server.network.*; +import cucky.jguard.server.probe.ProbeThread; + +public class Main { + + public static final int VERSION = 1; + public static final int CLIENT_MIN_VERSION = 26; + public static Properties config; + public static ArrayList maps; + public static ArrayList onlineClients = new ArrayList(); + + + public static void main(String[] args) { + + LogFile.clear(); + LogFile.printInfo("-------------------------"); + LogFile.printInfo(" jGuard Server "); + LogFile.printInfo("-------------------------"); + + LogFile.printInfo("Version: " + VERSION + " (" + BuilddDate.get() + ")"); + + /// + /// detekce operacniho systemu + /// + LogFile.printInfo("OS detect ..."); + if (OSValidator.isWindows()) { + LogFile.printInfo(" windows"); + } else if (OSValidator.isUnix()) { + LogFile.printInfo(" linux"); + } else { + LogFile.printInfo(" other"); + } + + /// + /// nahrani konfigurace + /// + LogFile.printInfo("Loading config ..."); + config = new Config().loadAll(); + if (config != null) { + LogFile.printInfo(" successfully"); + } else { + LogFile.printInfo(" fail"); + System.exit(0); + } + + /// + /// pripojeni k databazi + /// + new Database().connect(config.getProperty("mysql_server"), + config.getProperty("mysql_port"), + config.getProperty("mysql_database"), + config.getProperty("mysql_user"), + config.getProperty("mysql_password")); + + /// + /// nacteni map + /// + LogFile.printInfo("Loading map and object list ..."); + maps = Database.getMapList(); + LogFile.printInfo(" load " + maps.size() + " maps"); + + + /// + /// spusteni sond + /// + ProbeThread pt = new ProbeThread(); + pt.start(); + + for (Map m : maps) { + for (MapObject obj : m.getObjects()) { + if (obj.isActive()) { + ProbeThread.addPingProbe(obj.getIp(), obj.getId()); + } + } + } + + /// + /// spusteni serveru + /// + new Server().start(Integer.valueOf(config.getProperty("server_port"))); + + + + } + +} diff --git a/src/cucky/jguard/server/ServerMessageParser.java b/src/cucky/jguard/server/ServerMessageParser.java new file mode 100644 index 0000000..0312844 --- /dev/null +++ b/src/cucky/jguard/server/ServerMessageParser.java @@ -0,0 +1,263 @@ +package cucky.jguard.server; + +import io.netty.channel.Channel; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.util.concurrent.GlobalEventExecutor; +import cucky.jGuard.lib.LogFile; +import cucky.jGuard.lib.Message; +import cucky.jGuard.lib.Status; +import cucky.jGuard.lib.object.ObjectType; +import cucky.jGuard.lib.object.Map; +import cucky.jGuard.lib.object.MapObject; +import cucky.jGuard.lib.object.ObjectConnection; +import cucky.jGuard.lib.object.OnlineClients; +import cucky.jguard.server.probe.ProbeThread; +import java.net.InetSocketAddress; + +public class ServerMessageParser { + + MapObject mo; + + private Channel currentClient; + private static final ChannelGroup channels = new DefaultChannelGroup( + "containers", GlobalEventExecutor.INSTANCE); + + public ServerMessageParser(Channel currentClient) { + this.currentClient = currentClient; + } + + public void parse(Message msg) { + + System.out.println("-> Message type: " + msg.getType()); + + switch (msg.getType()) { + + case Message.CLIENT_VERSION: + + int client_version = (int) msg.getMsg(); + if (client_version < Main.CLIENT_MIN_VERSION) { + LogFile.printInfo("Zastaralý klient. Odeslán požadavek na aktualizaci (" + ((InetSocketAddress) currentClient.remoteAddress()).getHostName() + ")"); + currentClient.writeAndFlush(new Message(Message.UPDATE, null)); + } else { + LogFile.printInfo("Pozadavek na autorizaci odeslan (" + ((InetSocketAddress) currentClient.remoteAddress()).getHostName() + ")"); + // odeslat autorizacni udaje + currentClient.writeAndFlush(new Message(Message.AUTH_REQUEST, null)); + + } + break; + + + case Message.AUTH: + String[] userData = (String[]) msg.getMsg(); + String username = userData[0]; + String password = userData[1]; + int platform = Integer.parseInt(userData[2]); + if (username.equals("michal") && password.equals("123555")) { + channels.add(currentClient); + + currentClient.writeAndFlush(new Message(Message.AUTH_SUCEFULL, null)); + + // pridat do seznamu klientu + Main.onlineClients.add(new OnlineClients( + String.valueOf(currentClient.id()), + username, // username + ((InetSocketAddress) currentClient.remoteAddress()).getAddress().getHostName(), // ip adresa + String.valueOf(((InetSocketAddress) currentClient.remoteAddress()).getPort()), // port + platform)); // platforma + // odeslat vsem nový seznam pripojenych klientu + sendAll(new Message(Message.ONLINE_CLIENTS, Main.onlineClients)); + // odeslat nastaveni serveru + currentClient.writeAndFlush(new Message(Message.SERVER_SETTINGS, Database.getServerSettings())); + // odeslat informace o prihlasenem uzivateli, opravneni atd + currentClient.writeAndFlush(new Message(Message.USER_INFO, Database.getUserInfo(username))); + // odeslat seznam map + for (Map i : Main.maps) { + currentClient.writeAndFlush(new Message(Message.MAP, i)); + } + // odesle seznam zarizeni + currentClient.writeAndFlush(new Message(Message.LIST_OBJECT_TYPE, Database.listObjectType())); + // zapise do logu + LogFile.printInfo("Uživatel: " + username + " přihlášen (" + ((InetSocketAddress) currentClient.remoteAddress()).getAddress().getHostName() + ")"); + } else { + LogFile.printErr("Uživatel: " + username + " nebyl přihlášen - chybné údaje (" + ((InetSocketAddress) currentClient.remoteAddress()).getAddress().getHostName() + ")"); + currentClient.writeAndFlush(new Message(Message.AUTH_FAIL, null)); + currentClient.disconnect(); + } + break; + + + case Message.ADD_MAP: + String mapName = (String) msg.getMsg(); + // vlozeni do databaze + int id = Database.insert("INSERT INTO maps (name) VALUES ('" + mapName + "')"); + // vlozeni do seznamu + Main.maps.add(new Map(id, mapName)); + // odeslani infomace o nove mape klientum + sendAll(new Message(Message.MAP, new Map(id, mapName))); + break; + + + case Message.REMOVE_MAP: + int map_deleted = (int) msg.getMsg(); + // smazání z databáze + Database.query("DELETE FROM maps WHERE id = " + map_deleted); + // odebrani z lokalniho seznamu + for (Map m : Main.maps) { + if (m.getId() == map_deleted) { + Main.maps.remove(m); + break; + } + } + // odeslani zmeny vsem + sendAll(new Message(Message.REMOVE_MAP, map_deleted)); + break; + + + case Message.SET_MAP_LOCK: + int[] data_lock = (int[]) msg.getMsg(); + for (Map ma : Main.maps) { + if (ma.getId() == data_lock[0]) { + ma.setLock((data_lock[1] == 1)); + } + } + // upravit informaci v databazi + Database.update("UPDATE maps SET locked='" + data_lock[1] + "' WHERE id=" + data_lock[0]); + // odeslani informace ostatnim + sendAll(new Message(Message.SET_MAP_LOCK, data_lock)); + break; + + + case Message.MOVE_OBJECT: + int[] data_move = (int[]) msg.getMsg(); + // upravit pozici v databazi + Database.update("UPDATE object SET x='" + data_move[2] + "', y='" + data_move[3] + "' WHERE id=" + data_move[1]); + // prepsat v lokalnim arraylistu + for (Map map : Main.maps) { + for (MapObject object : map.getObjects()) { + if (object.getId() == data_move[1]) { + object.setX(data_move[2]); + object.setY(data_move[3]); + // odeslat + sendAll(new Message(Message.UPDATE_OBJECT, object)); + break; + } + } + } + break; + + + case Message.ADD_OBJECT: + mo = (MapObject) msg.getMsg(); + // vlozeni do databaze + int id_new_obj = Database.addObject(mo); + if (id_new_obj != -1) { + + // nastavi id objektu + mo.setId(id_new_obj); + // prida do lokalniho seznamu + for (Map map : Main.maps) { + if (map.getId() == mo.getMap()) { + map.addObject(mo); + break; + } + } + // odeslani objektu klientum + sendAll(new Message(Message.ADD_OBJECT, mo)); + // spusteni sondy + if (mo.isActive() && !mo.getIp().equals("")) { + ProbeThread.addPingProbe(mo.getIp(), mo.getId()); + } + } else { + // odeslat klientovi zpravu že doslo k chybe + currentClient.writeAndFlush(new Message(Message.SERVER_MESSAGE, "Došlo k chybě")); + } + break; + + + case Message.UPDATE_OBJECT: + mo = (MapObject) msg.getMsg(); + // aktualizace v databázi + Database.updateObject(mo); + // aktualizace v lokalnim listě + for (Map map : Main.maps) { + if (map.getId() == mo.getMap()) { + map.updateObject(mo); + break; + } + } + // odeslání neznameho stavu + int[] data = { + mo.getMap(), // id mapy + mo.getId(), // id objektu + Status.NA // status + }; + sendAll(new Message(Message.STATE_UPDATE, data)); + // odeslani aktualizovaného objektu klientům + sendAll(new Message(Message.UPDATE_OBJECT, mo)); + // zastavit sondu a spustit znova + ProbeThread.removePingProbe(mo.getId()); + if (mo.isActive() && !mo.getIp().equals("")) { + ProbeThread.addPingProbe(mo.getIp(), mo.getId()); + } + break; + + + case Message.ADD_OBJECT_TYPE: + ObjectType objtype = (ObjectType) msg.getMsg(); + // pridani do databaze + int id_add_obj_type = Database.addDeviceType(objtype.getName(), objtype.getImgStr()); + // pridani id do objektu + objtype.setId(id_add_obj_type); + // odeslat novy objekt vsem + sendAll(new Message(Message.ADD_OBJECT_TYPE, objtype)); + break; + + + case Message.NEW_CONNECTION: + ObjectConnection oc = (ObjectConnection) msg.getMsg(); + // pridani do databaze + int id_add_con = Database.addObjectConnection(oc); + if (id_add_con != -1) { + for (Map map : Main.maps) { + if (map.getId() == oc.getMap()) { + // pridani do arraylistu + map.addObjectConnection(oc); + // odeslat nové propojeni klientum + sendAll(new Message(Message.NEW_CONNECTION, oc)); + break; + } + } + } else { + // odeslat klientovi zpravu že doslo k chybe + currentClient.writeAndFlush(new Message(Message.SERVER_MESSAGE, "Došlo k chybě")); + } + break; + + + + + default: + LogFile.printErr("Neznamy typ zpravy"); + + } + + } + + public static void sendAll(Message message) { + if (channels.isEmpty()) { + return; + } + channels.writeAndFlush(message); + } + + public void removeClient() { + // odebrani ze seznamu klientu + for (int i = 0; i < Main.onlineClients.size(); i++) { + if (Main.onlineClients.get(i).getId() == String.valueOf(currentClient.id())) { + Main.onlineClients.remove(i); + } + } + sendAll(new Message(Message.ONLINE_CLIENTS, Main.onlineClients)); + } +} diff --git a/src/cucky/jguard/server/probe/PacketCaptor.java b/src/cucky/jguard/server/probe/PacketCaptor.java new file mode 100644 index 0000000..280e723 --- /dev/null +++ b/src/cucky/jguard/server/probe/PacketCaptor.java @@ -0,0 +1,156 @@ +package cucky.jguard.server.probe; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.Arrays; +import cucky.jguard.server.Main; +import cucky.jGuard.lib.LogFile; +import jpcap.JpcapCaptor; +import jpcap.JpcapSender; +import jpcap.NetworkInterface; +import jpcap.NetworkInterfaceAddress; +import jpcap.packet.EthernetPacket; +import jpcap.packet.ICMPPacket; +import jpcap.packet.IPPacket; +import jpcap.packet.Packet; + +class PacketCaptor { + + private static final int DEFAULT_TTL = 32; + public static final short SEQ = 100; + public static final String DATA = "data"; + + private NetworkInterface device; + private InetAddress thisIP; + private byte[] gwmac; + private JpcapSender sender; + private JpcapCaptor captor; + + public PacketCaptor() throws Exception { + + //initialize Jpcap + NetworkInterface[] ifaces = JpcapCaptor.getDeviceList(); + LogFile.printDebug(ifaces.length + " network interface available"); + + for (NetworkInterface iface : ifaces) { + if (macAsString(iface.mac_address).equals(Main.config.get("interface_mac"))) { + device = iface; + break; + } + } + + captor = JpcapCaptor.openDevice(device, 1000, false, 10); + + for (NetworkInterfaceAddress addr : device.addresses) { + if (addr.address instanceof Inet4Address) { + thisIP = addr.address; + LogFile.printInfo("Local adress: " + thisIP.getHostAddress()); + break; + } + } + if (!((String) Main.config.get("gateway_mac")).isEmpty()) { + gwmac = macToByte((String) Main.config.get("gateway_mac")); + } else { + gwmac = getMacGateway(); + } + + + captor.setFilter("icmp and dst host " + thisIP.getHostAddress(), false); + sender = captor.getJpcapSenderInstance(); + + } + + /** + * odesle icmp packet na zadanou adresu + * + * @param address - cilova adresa + * @param seq - cislo sekvence + * @throws UnknownHostException + */ + public void sendPacket(String address, short seq) throws UnknownHostException { + //create ICMP packet + ICMPPacket icmp = new ICMPPacket(); + icmp.type = ICMPPacket.ICMP_ECHO; + icmp.seq = seq; + icmp.id = 0; + icmp.setIPv4Parameter(0, false, false, false, 0, false, false, false, 0, 0, DEFAULT_TTL, IPPacket.IPPROTO_ICMP, + thisIP, InetAddress.getByName(address)); + icmp.data = DATA.getBytes(); + EthernetPacket ether = new EthernetPacket(); + ether.frametype = EthernetPacket.ETHERTYPE_IP; + ether.src_mac = device.mac_address; + ether.dst_mac = gwmac; + icmp.datalink = ether; + sender.sendPacket(icmp); + } + + public Packet getPacket() { + return captor.getPacket(); + } + + /** + * prevede mac adresu ve tvaru xx-xx-xx-xx-xx-xx na byte[] + * + * @param macAddress - string ve tvaru xx-xx-xx-xx-xx-xx + * @return byte[] + */ + private byte[] macToByte(String macAddress) { + String[] macAddressParts = macAddress.split("-"); + byte[] macAddressBytes = new byte[6]; + for (int i = 0; i < 6; i++) { + Integer hex = Integer.parseInt(macAddressParts[i], 16); + macAddressBytes[i] = hex.byteValue(); + } + return macAddressBytes; + } + + /** + * prevede mac adresu ve formatu byte[] na retezec + * + * @param bytes + * @return + */ + private String macAsString(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (byte b : bytes) { + if (!first) { + sb.append(String.format("-%02X", b)); + } else { + sb.append(String.format("%02X", b)); + first = false; + } + + } + return sb.toString(); + } + + /** + * vrátí mac adresu výchozí brány + * + * @return byte[] + * @throws Exception + */ + private byte[] getMacGateway() throws Exception { + byte[] mac = null; + LogFile.printDebug("Dynamic GW search in progress..."); + InetAddress pingAddr = InetAddress.getByName("www.google.com"); + captor.setFilter("tcp and dst host " + pingAddr.getHostAddress(), true); + while (true) { + new URL("http://www.google.com").openStream().close(); + Packet ping = captor.getPacket(); + if (ping == null) { + LogFile.printDebug("cannot obtain MAC address of default gateway."); + System.exit(-1); + } else if (Arrays.equals(((EthernetPacket) ping.datalink).dst_mac, device.mac_address)) { + continue; + } + mac = ((EthernetPacket) ping.datalink).dst_mac; + break; + } + LogFile.printDebug("Default gateway found -- " + Arrays.toString(mac)); + return mac; + } +} diff --git a/src/cucky/jguard/server/probe/ProbeThread.java b/src/cucky/jguard/server/probe/ProbeThread.java new file mode 100644 index 0000000..7e78eb1 --- /dev/null +++ b/src/cucky/jguard/server/probe/ProbeThread.java @@ -0,0 +1,223 @@ +package cucky.jguard.server.probe; + +import cucky.jGuard.lib.LogFile; +import cucky.jGuard.lib.Message; +import cucky.jGuard.lib.object.Map; +import cucky.jGuard.lib.object.MapObject; +import cucky.jGuard.lib.Status; +import cucky.jguard.server.Main; +import cucky.jguard.server.ServerMessageParser; +import java.net.UnknownHostException; +import java.util.ArrayList; +import jpcap.packet.ICMPPacket; +import jpcap.packet.Packet; + +public class ProbeThread extends Thread { + + private static final int RUN_DELAY = 5000; + + protected static ArrayList sended = new ArrayList(); + private static PacketCaptor pc; + private static boolean stop = false; + + public ProbeThread() { + super("probe-thread"); + } + + @Override + public void run() { + super.run(); + + LogFile.printInfo("Probe thread run"); + + try { + pc = new PacketCaptor(); + } catch (Exception ex) { + LogFile.printErr("[ProbeThread] PacketCaptor exception: " + ex.getMessage()); + } + + CaptureThread ct = new CaptureThread(); + ct.start(); + + TimeoutThread to = new TimeoutThread(); + to.start(); + } + + /** + * Přidá do fronty zařízení se sondou + * + * @param address + */ + public static void addPingProbe(String address, int deviceId) { + Thread th = new Thread() { + @Override + public void run() { + try { + super.run(); + Thread.sleep(RUN_DELAY); + // odesle packet + pc.sendPacket(address, PacketCaptor.SEQ); + // zaradi zarizeni mezi odeslane + sended.add(new SendedProbe(SendedProbe.TYPE_PING, deviceId, address, System.currentTimeMillis())); + } catch (InterruptedException | UnknownHostException ex) { + LogFile.printErr("addProbe exception: " + ex.getMessage()); + } + LogFile.printInfo("Spusten ping na: " + address); + } + + }; + th.start(); + + } + + /** + * odebere ping sondu zarizeni + * + * @param deviceId + */ + public static void removePingProbe(int deviceId) { + for (SendedProbe sp : sended) { + if (sp.getDeviceId() == deviceId) { + sended.remove(sp); + break; + } + } + } + + /** + * Aktualizuje ve frontě informace o sonde + * + * @param address + */ + private static void updateProbe(String address) { + try { + for (SendedProbe probeData : sended) { + if (probeData.getAddress().equals(address)) { + // odesle packet + pc.sendPacket(address, PacketCaptor.SEQ); + // zaradi zarizeni mezi odeslane + probeData.setTime(System.currentTimeMillis()); + break; + } + } + } catch (UnknownHostException ex) { + LogFile.printErr("addProbe exception: " + ex.getMessage()); + } + } + + /** + * Odchytavani packetu + */ + private static void capturePacket() { + Packet packet = pc.getPacket(); + + if (packet != null) { + long packetRecTime = ((long) packet.sec) * 1000 + packet.usec / 1000; // TODO + if (packet instanceof ICMPPacket) { + ICMPPacket p = (ICMPPacket) packet; + + if (p.seq == PacketCaptor.SEQ) { + if (p.type == ICMPPacket.ICMP_ECHOREPLY) { + for (SendedProbe pd : sended) { + + // POKUD JDE O SONDU TYPU PING A ZAROVEN JDE O STEJNOU ADRESU + if (pd.getAddress().equals(p.src_ip.getHostAddress()) && pd.getType() == SendedProbe.TYPE_PING) { + + long latency = System.currentTimeMillis() - pd.getTime(); // TODO oveřit správný výpočet + LogFile.printDebug("Odpoved od: " + p.src_ip.getHostAddress() + " time: " + latency + " ms"); + + // pripadna aktualizace stavu v seznamu + updateStatus(pd, Status.OK); + + // nové odeslani icmp packetu + updateProbe(pd.getAddress()); + break; + } + } + } else { + LogFile.printDebug("ICMP packet type: " + p.type); + //fail("ping", p.src_ip.getHostAddress()); + } + } + + } + + } + } + + private static void updateStatus(SendedProbe pd, int currentStatus) { + for (Map map : Main.maps) { + for (MapObject obj : map.getObjects()) { + if (pd.getDeviceId() == obj.getId()) { + if (obj.getStatus() != currentStatus) { + // ulozit do arraylistu + obj.setStatus(currentStatus); + // odeslat novy status vsem + int[] data = { + obj.getMap(), // id mapy + obj.getId(), // id objektu + currentStatus // status + }; + ServerMessageParser.sendAll(new Message(Message.STATE_UPDATE, data)); + } + break; + + } + } + } + } + + /** + * Vlakno pro nonstop odchyt packetu + */ + private static class CaptureThread extends Thread { + + public CaptureThread() { + super("packet-capture"); + } + + @Override + public void run() { + super.run(); //To change body of generated methods, choose Tools | Templates. + LogFile.printDebug("Capture Thread run"); + while (!stop) { + capturePacket(); + } + } + } + + /** + * Vlakno pro timeout sondy ve fronte + */ + private static class TimeoutThread extends Thread { + + // testovat se bude 1x za sekundu + private static final int CHECK_INTERVAL = 1000; + + public TimeoutThread() { + super("timeout-checker"); + } + + @Override + public void run() { + + while (!stop) { + try { + Thread.sleep(CHECK_INTERVAL); + for (SendedProbe pd : sended) { + if (System.currentTimeMillis() > (pd.getTime() + CHECK_INTERVAL) && pd.getType() == SendedProbe.TYPE_PING) { + // pripadna aktualizace stavu v seznamu + updateStatus(pd, Status.OFFLINE); + // nové odeslani icmp packetu + updateProbe(pd.getAddress()); + } + } + } catch (InterruptedException ex) { + LogFile.printErr("TimeoutThread exception: " + ex.getMessage()); + } + } + + } + } + +} diff --git a/src/cucky/jguard/server/probe/SendedProbe.java b/src/cucky/jguard/server/probe/SendedProbe.java new file mode 100644 index 0000000..b78aac5 --- /dev/null +++ b/src/cucky/jguard/server/probe/SendedProbe.java @@ -0,0 +1,56 @@ +package cucky.jguard.server.probe; + + +public class SendedProbe { + + public static final int TYPE_PING = 1; + public static final int TYPE_SNMP = 2; + + private int type; + private int deviceId; + private String address; + private long time; + + public SendedProbe(int type, int deviceId, String address, long time) { + this.type = type; + this.deviceId = deviceId; + this.address = address; + this.time = time; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + + + +} diff --git a/src/cucky/jquard/server/network/Server.java b/src/cucky/jquard/server/network/Server.java new file mode 100644 index 0000000..3b51bc4 --- /dev/null +++ b/src/cucky/jquard/server/network/Server.java @@ -0,0 +1,45 @@ +package cucky.jquard.server.network; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.util.SelfSignedCertificate; +import cucky.jGuard.lib.LogFile; +import cucky.jguard.server.Config; + +public class Server { + + public void start(int port) { + EventLoopGroup producer = new NioEventLoopGroup(); + EventLoopGroup consumer = new NioEventLoopGroup(); + + try { + SelfSignedCertificate ssc = new SelfSignedCertificate(); + SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) + .build(); + + ServerBootstrap bootstrap = new ServerBootstrap() + .group(producer, consumer) + .channel(NioServerSocketChannel.class) + .childHandler(new ServerAdapterInitializer(sslCtx)); + + LogFile.printInfo("Server started on port " + port); + + ChannelFuture f = bootstrap.bind(port).sync(); + f.channel().closeFuture().sync(); + + + } catch (Exception e) { + LogFile.printErr("Server error: " + e.getMessage()); + } finally { + producer.shutdownGracefully(); + consumer.shutdownGracefully(); + } + + } + +} diff --git a/src/cucky/jquard/server/network/ServerAdapterHandler.java b/src/cucky/jquard/server/network/ServerAdapterHandler.java new file mode 100644 index 0000000..f064f42 --- /dev/null +++ b/src/cucky/jquard/server/network/ServerAdapterHandler.java @@ -0,0 +1,48 @@ +package cucky.jquard.server.network; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.group.ChannelGroup; +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.util.concurrent.GlobalEventExecutor; +import cucky.jGuard.lib.LogFile; +import cucky.jGuard.lib.Message; +import cucky.jguard.server.ServerMessageParser; + +public class ServerAdapterHandler extends SimpleChannelInboundHandler { + + private static final ChannelGroup channels = new DefaultChannelGroup( + "containers", GlobalEventExecutor.INSTANCE); + + @Override + protected void channelRead0(ChannelHandlerContext chc, Message msg) throws Exception { + Channel currentClient = chc.channel(); + // predani prichozi zpravy ke zpracovani + new ServerMessageParser(currentClient).parse(msg); + } + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + super.channelRegistered(ctx); + Channel currentClient = ctx.channel(); + currentClient.writeAndFlush(new Message(Message.CLIENT_VERSION, null)); + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + super.channelUnregistered(ctx); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + new ServerMessageParser(ctx.channel()).removeClient(); + } + + public static void sendAll(Message message) { + if (channels.isEmpty()) { + return; + } + channels.writeAndFlush(message); + } +} diff --git a/src/cucky/jquard/server/network/ServerAdapterInitializer.java b/src/cucky/jquard/server/network/ServerAdapterInitializer.java new file mode 100644 index 0000000..c4c1f18 --- /dev/null +++ b/src/cucky/jquard/server/network/ServerAdapterInitializer.java @@ -0,0 +1,34 @@ +package cucky.jquard.server.network; + + + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.serialization.ClassResolvers; +import io.netty.handler.codec.serialization.ObjectDecoder; +import io.netty.handler.codec.serialization.ObjectEncoder; +import io.netty.handler.ssl.SslContext; + +public class ServerAdapterInitializer extends ChannelInitializer { + + private final SslContext sslCtx; + + public ServerAdapterInitializer(SslContext sslCtx) { + this.sslCtx = sslCtx; + } + + + + @Override + protected void initChannel(SocketChannel channel) throws Exception { + ChannelPipeline pipeline = channel.pipeline(); + + pipeline.addLast(sslCtx.newHandler(channel.alloc())); + pipeline.addLast("decoder", new ObjectDecoder(ClassResolvers.cacheDisabled(getClass().getClassLoader()))); + pipeline.addLast("encoder", new ObjectEncoder()); + + pipeline.addLast("handler", new ServerAdapterHandler()); + } + +} \ No newline at end of file