From 97c8e28f5ea90d2c51d62f1f46fcf707ee78687e Mon Sep 17 00:00:00 2001 From: epollia <35440159+epollia@users.noreply.github.com> Date: Sat, 14 Mar 2020 22:36:10 +0700 Subject: [PATCH 1/6] application.properties application.properties - file for spring boot --- src/main/resources/application.properties | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..9681a88 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,12 @@ +sshd.shell.port=8437 +sshd.shell.enabled=true +sshd.shell.username=cbadmin +sshd.shell.password=- +sshd.shell.host=127.0.0.1 +sshd.shell.auth.authType=SIMPLE +sshd.shell.prompt.title=cbackup +spring.main.banner-mode=off +cbackup.scheme=http +cbackup.site=localhost/index.php +cbackup.token=- +#logging.level.expect4j=trace \ No newline at end of file From 0b37359661c3bd67bbb0006f1a5c072ea34f4027 Mon Sep 17 00:00:00 2001 From: epollia <35440159+epollia@users.noreply.github.com> Date: Sat, 14 Mar 2020 22:37:26 +0700 Subject: [PATCH 2/6] add dynamic var in snmp_set_value --- src/main/java/snmp/GeneralSnmp.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/snmp/GeneralSnmp.java b/src/main/java/snmp/GeneralSnmp.java index a498b08..f85c8e7 100644 --- a/src/main/java/snmp/GeneralSnmp.java +++ b/src/main/java/snmp/GeneralSnmp.java @@ -376,6 +376,18 @@ protected Boolean performJobs() case 2: return false; } + + varInjectResult = this.injectVariable(snmpSetValue); + switch(varInjectResult.getStatus()) { + case 0: + snmpSetValue = varInjectResult.getResult(); + break; + case 1: + skipCommand = true; + break; + case 2: + return false; + } /* * Parsing job timeout to integer From 888e7bc2635ef08dd13177966bc23fec6ab9fd8b Mon Sep 17 00:00:00 2001 From: epollia <35440159+epollia@users.noreply.github.com> Date: Sat, 14 Mar 2020 22:40:19 +0700 Subject: [PATCH 3/6] add telnetAuth for BDCOM BDCOM output double string with promt (#). --- src/main/java/telnet/FactoryMethodTelnet.java | 3 +- src/main/java/telnet/_BDCOM_Telnet.java | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/main/java/telnet/_BDCOM_Telnet.java diff --git a/src/main/java/telnet/FactoryMethodTelnet.java b/src/main/java/telnet/FactoryMethodTelnet.java index b63426f..e7b7383 100644 --- a/src/main/java/telnet/FactoryMethodTelnet.java +++ b/src/main/java/telnet/FactoryMethodTelnet.java @@ -47,6 +47,7 @@ public class FactoryMethodTelnet { private static final Map> models = new HashMap>() {{ put("Mikrotik", null); put("Nortel", null); + put("BDCOM", null); //put("Extream", null); todo implement }}; @@ -68,7 +69,7 @@ public GeneralTelnet getProtocolObject(Map coordinates, Map. + */ + +import abstractions.DTOExpectSendPair; +import abstractions.DTOSendExpectPair; +import abstractions.DTOVariableConvertResult; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +/* + * Custom telnet init + */ +import expect4j.Expect4j; +import org.apache.commons.net.io.FromNetASCIIInputStream; +import org.apache.commons.net.io.ToNetASCIIOutputStream; +import org.apache.commons.net.telnet.EchoOptionHandler; +import org.apache.commons.net.telnet.SuppressGAOptionHandler; +import org.apache.commons.net.telnet.TelnetClient; +import org.apache.commons.net.telnet.TerminalTypeOptionHandler; + +/** + * Vendor Nortel general telnet class + * @noinspection unused + */ +public class _BDCOM_Telnet extends GeneralTelnet { + + /** + * Constructor + * + * @param coordinates - schedule, task, node, etc.. + * @param settings - app settings + * @param jobs - sorted jobs + * @param credentials - credentials + * @param variables - variable list + */ + public _BDCOM_Telnet(Map coordinates, Map settings, Map credentials, Map> jobs, Map variables) + { + /* + * Parent constructor + */ + super(coordinates, settings, credentials, jobs, variables); + + /* + * Set ENTER_CHARACTER + */ + this.ENTER_CHARACTER = "\r\n"; + this.controlSeqences.put("%%SEQ(ENTER)%%", this.ENTER_CHARACTER); + } + + + /** + * Expect init + * Send credentials + * Get device prompt + * Send commands + * + * @return Boolean + * @noinspection Duplicates + */ + @Override + protected Boolean telnetAuth() { + for(DTOExpectSendPair currentPair : this.telnetAuthSequence) { + if(!this.executeAuth(currentPair)) { + return false; + } + } + try { + this.expect.expect("#"); + } catch (Exception e) { + e.printStackTrace(); + } + return true; + } + +} From 8dfa39b3b364d90b7ea182a24f32b47270566cc9 Mon Sep 17 00:00:00 2001 From: epollia <35440159+epollia@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:24:41 +0700 Subject: [PATCH 4/6] Add custom ssh for Infinet --- src/main/java/ssh/FactoryMethodSsh.java | 1 + src/main/java/ssh/_Infinet_Ssh.java | 54 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/main/java/ssh/_Infinet_Ssh.java diff --git a/src/main/java/ssh/FactoryMethodSsh.java b/src/main/java/ssh/FactoryMethodSsh.java index 4d916c4..01bcb07 100644 --- a/src/main/java/ssh/FactoryMethodSsh.java +++ b/src/main/java/ssh/FactoryMethodSsh.java @@ -46,6 +46,7 @@ public class FactoryMethodSsh { private static final Map> models = new HashMap>() {{ put("Mikrotik", null); + put("Infinet", null); //put("Extream", null); todo implement }}; diff --git a/src/main/java/ssh/_Infinet_Ssh.java b/src/main/java/ssh/_Infinet_Ssh.java new file mode 100644 index 0000000..4022855 --- /dev/null +++ b/src/main/java/ssh/_Infinet_Ssh.java @@ -0,0 +1,54 @@ +/* + * This file is part of cBackup, network equipment configuration backup tool + * Copyright (C) 2017, Oļegs Čapligins, Imants Černovs, Dmitrijs Galočkins + * + * cBackup is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package ssh; + +import abstractions.DTOExpectSendPair; +import abstractions.DTOVariableConvertResult; +import java.util.Map; + + +/** + * Vendor Mikrotik general ssh class + * @noinspection unused + */ +public class _Infinet_Ssh extends GeneralSsh { + + /** + * Constructor + * + * @param coordinates - schedule, task, node, etc.. + * @param settings - app settings + * @param credentials - credentials + * @param jobs - sorted jobs + * @param variables - variable list + */ + public _Infinet_Ssh(Map coordinates, Map settings, Map credentials, Map> jobs, Map variables) + { + /* + * Parent constructor + */ + super(coordinates, settings, credentials, jobs, variables); + /* + * Set ENTER_CHARACTER + */ + ENTER_CHARACTER = "\r\n"; + this.controlSeqences.put("%%SEQ(ENTER)%%", this.ENTER_CHARACTER); + + } + +} From dd09618d29584c3f570f84ccd7a7192a846537ca Mon Sep 17 00:00:00 2001 From: epollia <35440159+epollia@users.noreply.github.com> Date: Mon, 6 Apr 2020 17:18:21 +0700 Subject: [PATCH 5/6] Add files via upload --- src/main/java/snmp/GeneralSnmp.java | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/java/snmp/GeneralSnmp.java b/src/main/java/snmp/GeneralSnmp.java index f85c8e7..bd5792e 100644 --- a/src/main/java/snmp/GeneralSnmp.java +++ b/src/main/java/snmp/GeneralSnmp.java @@ -377,18 +377,6 @@ protected Boolean performJobs() return false; } - varInjectResult = this.injectVariable(snmpSetValue); - switch(varInjectResult.getStatus()) { - case 0: - snmpSetValue = varInjectResult.getResult(); - break; - case 1: - skipCommand = true; - break; - case 2: - return false; - } - /* * Parsing job timeout to integer */ @@ -408,6 +396,17 @@ protected Boolean performJobs() /* * --------SNMP SET CASE---------- */ + varInjectResult = this.injectVariable(snmpSetValue); + switch(varInjectResult.getStatus()) { + case 0: + snmpSetValue = varInjectResult.getResult(); + break; + case 1: + skipCommand = true; + break; + case 2: + return false; + } // Case: empty SNMP set value if(snmpSetValue == null || snmpSetValue.length() == 0) { From a3b62dc3f264035fd999c2cb7b169ed0e0ad87c2 Mon Sep 17 00:00:00 2001 From: epollia Date: Mon, 26 Oct 2020 23:29:03 +0700 Subject: [PATCH 6/6] add CDATA telnet worker --- src/main/java/core/Scheduler.java | 5 + src/main/java/core/WorkerDiscovery.java | 27 ++- src/main/java/telnet/FactoryMethodTelnet.java | 1 + src/main/java/telnet/_CDATA_Telnet.java | 201 ++++++++++++++++++ src/main/resources/application.properties | 1 + 5 files changed, 230 insertions(+), 5 deletions(-) create mode 100644 src/main/java/telnet/_CDATA_Telnet.java diff --git a/src/main/java/core/Scheduler.java b/src/main/java/core/Scheduler.java index 11c2f4f..f4caba9 100644 --- a/src/main/java/core/Scheduler.java +++ b/src/main/java/core/Scheduler.java @@ -51,6 +51,8 @@ public class Scheduler extends AbstractCoreUnit { private String site; @Value("${cbackup.token}") private String token; + @Value("${cbackup.discoverylen}") + private String discoverylen; /** @@ -769,6 +771,9 @@ private void init() throws Exception { try { this.settings = this.gson.fromJson(settingsJson, settingsType); + this.settings.put("discoverylen", this.discoverylen); + + } catch (Exception e) { this.logSystemException("ERROR", "SCHEDULER INIT", "Can't parse settings from json.", e); throw new Exception("Can't parse settings from json.", e); diff --git a/src/main/java/core/WorkerDiscovery.java b/src/main/java/core/WorkerDiscovery.java index d476b69..4ebe820 100644 --- a/src/main/java/core/WorkerDiscovery.java +++ b/src/main/java/core/WorkerDiscovery.java @@ -36,7 +36,6 @@ import org.snmp4j.util.DefaultPDUFactory; import org.snmp4j.util.TreeEvent; import org.snmp4j.util.TreeUtils; - import java.util.*; import java.util.concurrent.Callable; @@ -47,15 +46,16 @@ import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; - /** * Device SNMP discovery class */ + public class WorkerDiscovery extends AbstractCoreUnit implements Callable { - + private Gson gson = new Gson(); + private Integer snmpVer; private Integer snmpPort; private String snmpRead; @@ -141,6 +141,7 @@ private static Map createMap() { */ public Boolean call() { + // parse snmpRetries, snmpTimeout if(!this.extractSettings()) { return false; @@ -166,6 +167,7 @@ private Boolean extractSettings() { String retries = this.settings.get("snmpRetries"); String timeout = this.settings.get("snmpTimeout"); + /* * Set snmp retries @@ -237,6 +239,7 @@ private Boolean getDiscovery() { * SNMP object init */ try { + this.snmp = new Snmp(new DefaultUdpTransportMapping()); this.snmp.listen(); @@ -457,7 +460,7 @@ private Boolean sendWalk() */ private Boolean sendRequest() { - + PDU responsePDU; ResponseEvent responseEvent; @@ -525,7 +528,21 @@ private Boolean sendRequest() try { String sOid = vb.getOid().toString(); String sVar = vb.getVariable().toString(); - this.result.put(discoveryOids.get(sOid), sVar); + Integer llen = Integer.parseInt(this.settings.get("discoverylen")); + if (discoveryOids.get(sOid) == "sys_description" && llen > 0) { + + if (sVar.length() > llen) { + this.result.put(discoveryOids.get(sOid), sVar.substring(0,llen)); + } + else{ + this.result.put(discoveryOids.get(sOid), sVar); + } + + } + else{ + this.result.put(discoveryOids.get(sOid), sVar); + } + } catch (Exception e) { String responsePduVectorConvertMessage = "Task " + this.coordinates.get("taskName") + diff --git a/src/main/java/telnet/FactoryMethodTelnet.java b/src/main/java/telnet/FactoryMethodTelnet.java index e7b7383..a10e80e 100644 --- a/src/main/java/telnet/FactoryMethodTelnet.java +++ b/src/main/java/telnet/FactoryMethodTelnet.java @@ -48,6 +48,7 @@ public class FactoryMethodTelnet { put("Mikrotik", null); put("Nortel", null); put("BDCOM", null); + put("CDATA", null); //put("Extream", null); todo implement }}; diff --git a/src/main/java/telnet/_CDATA_Telnet.java b/src/main/java/telnet/_CDATA_Telnet.java new file mode 100644 index 0000000..48f1bf0 --- /dev/null +++ b/src/main/java/telnet/_CDATA_Telnet.java @@ -0,0 +1,201 @@ +package telnet;/* + * This file is part of cBackup, network equipment configuration backup tool + * Copyright (C) 2017, Oļegs Čapligins, Imants Černovs, Dmitrijs Galočkins + * + * cBackup is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import abstractions.DTOSendExpectPair; +import abstractions.DTOVariableConvertResult; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +/* + * Custom telnet init + */ +import expect4j.Expect4j; +import org.apache.commons.net.io.FromNetASCIIInputStream; +import org.apache.commons.net.io.ToNetASCIIOutputStream; +import org.apache.commons.net.telnet.EchoOptionHandler; +import org.apache.commons.net.telnet.SuppressGAOptionHandler; +import org.apache.commons.net.telnet.TelnetClient; +import org.apache.commons.net.telnet.TerminalTypeOptionHandler; +import org.apache.commons.net.telnet.WindowSizeOptionHandler; + +/** + * Vendor Nortel general telnet class + * @noinspection unused + */ +public class _CDATA_Telnet extends GeneralTelnet { + + /** + * Constructor + * + * @param coordinates - schedule, task, node, etc.. + * @param settings - app settings + * @param jobs - sorted jobs + * @param credentials - credentials + * @param variables - variable list + */ + public _CDATA_Telnet(Map coordinates, Map settings, Map credentials, Map> jobs, Map variables) + { + /* + * Parent constructor + */ + super(coordinates, settings, credentials, jobs, variables); + + /* + * Set ENTER_CHARACTER + */ + /*this.ENTER_CHARACTER = "\r";*/ + this.controlSeqences.put("%%SEQ(ENTER)%%", this.ENTER_CHARACTER); + } + + + /** + * Expect init + * Send credentials + * Get device prompt + * Send commands + * + * @return Boolean + * @noinspection Duplicates + */ + @Override + protected Boolean performJobs() + { + + /* + * Object Expect4j init + */ + try { + + final TelnetClient client = new TelnetClient("VT100"); + + TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, true); + EchoOptionHandler echoopt = new EchoOptionHandler(false, false, false, true); + SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(false, false, false, false); + WindowSizeOptionHandler winopt = new WindowSizeOptionHandler(500, 500, false,true,true,false); + + client.addOptionHandler(ttopt); + client.addOptionHandler(echoopt); + client.addOptionHandler(gaopt); + client.addOptionHandler(winopt); + + client.connect(this.coordinates.get("nodeIp"), this.telnetPort); + InputStream is = new FromNetASCIIInputStream(client.getInputStream()); + OutputStream os = new ToNetASCIIOutputStream(client.getOutputStream()); + + + this.expect = new Expect4j(is, os) { + public void close() { + super.close(); + try { + client.disconnect(); + } catch (IOException var2) { + + } + } + }; + } + catch (Exception e) { + String telnetObjectInitMessage = "Task " + this.coordinates.get("taskName") + ", node " + this.coordinates.get("nodeId") + ": can't create telnet expect object."; + this.logException("ERROR", "NODE REQUEST", telnetObjectInitMessage, e); + return false; + } + + + /* + * Telnet authorization + */ + if(!this.telnetAuth()) { + return false; + } + + /* + * Get device prompt + */ + if(!this.setRealPrompt()) { + return false; + } + + /* + * Setting jobs to expect-send pairs + */ + for(Map.Entry> entry : this.jobs.entrySet()) { + + Map jobInfo = entry.getValue(); + + String currentCommand = jobInfo.get("command_value"); + String currentTableField = jobInfo.get("table_field"); + String currentTimeout = jobInfo.get("timeout"); + String currentVariable = jobInfo.get("command_var"); + + if(currentVariable != null && currentVariable.length() > 0) { + this.variables.put(currentVariable, null); + } + + Integer currentTimeoutInt; + + if (currentTableField != null && currentTableField.length() > 0) { + this.result.data.put(currentTableField, ""); + } + + /* + * Parsing command telnet timeout to integer + */ + if(currentTimeout != null && currentTimeout.length() > 0) { + try { + currentTimeoutInt = Integer.parseInt(currentTimeout); + } + catch(NumberFormatException e) { + String telnetCurrentTimeoutParseMessage = "Task " + this.coordinates.get("taskName") + ", node " + this.coordinates.get("nodeId") + + ": can't parse job telnet timeout to integer."; + this.logException("ERROR", "NODE REQUEST", telnetCurrentTimeoutParseMessage, e); + return false; + } + } + else { + currentTimeoutInt = this.telnetTimeout; + } + + /* + * Set prompt to expect(custom or not) + */ + String customPrompt = jobInfo.get("cli_custom_prompt"); + String currentPrompt; + Boolean replaceExpect = true; + if (customPrompt == null || customPrompt.length()==0) { + currentPrompt = this.telnetEscapedRealPrompt; + } + else { + currentPrompt = customPrompt; + replaceExpect = false; + } + + DTOSendExpectPair currentPair = new DTOSendExpectPair(currentPrompt, currentCommand, currentTableField, currentTimeoutInt, currentVariable, replaceExpect); + this.telnetCommands.add(currentPair); + + } + + /* + * Job commands exec + */ + return this.telnetCommands(); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9681a88..2365364 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,6 +7,7 @@ sshd.shell.auth.authType=SIMPLE sshd.shell.prompt.title=cbackup spring.main.banner-mode=off cbackup.scheme=http +cbackup.discoverylen=0 cbackup.site=localhost/index.php cbackup.token=- #logging.level.expect4j=trace \ No newline at end of file