1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-23 03:37:15 +01:00

fixes #990 Use scp top deploy configuration to Cisco router

This commit is contained in:
Vadim Kurland 2009-12-23 01:02:51 +00:00
parent 39f8937bdb
commit 4583645445
19 changed files with 637 additions and 588 deletions

View File

@ -1 +1 @@
#define BUILD_NUM 2245
#define BUILD_NUM 2248

View File

@ -1,5 +1,13 @@
2009-12-22 vadim <vadim@vk.crocodile.org>
* src/res/configlets/ios/installer_commands_reg_user: Built-in
installer can use command scp to copy IOS configuration to the
router using ssh and then command "copy file running-config" to
activate it. This method is much faster than running
configuration line by line. The router should be configured with
ssh v2 and scp server. This method can be combined with
rollback (by reload or EEM).
* src/res/configlets/ios/installer_commands_pre_config: Built-in
policy installer uses EEM (Embedded Event Manager) on IOS 12.4 or
later to schedule automatic configuration rollback instead of

View File

@ -33,6 +33,7 @@
#include "FWBSettings.h"
#include "FWWindow.h"
#include "SSHSession.h"
#include "SSHUnx.h"
#include "Configlet.h"
#include "fwbuilder/Resources.h"
@ -446,8 +447,30 @@ void FirewallInstaller::runJobs()
* commandFinished(). This slot checks termination status of the process
* and if it was successfull, it schedules call to runJobs()
*/
void FirewallInstaller::copyFile(const QString&, const QString&)
void FirewallInstaller::copyFile(const QString &local_name, const QString &remote_name)
{
//QString platform = cnf->fwobj->getStr("platform").c_str();
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("latin1"));
QStringList args;
packSCPArgs(local_name, remote_name, args);
inst_dlg->addToLog( tr("Copying %1 -> %2:%3\n")
.arg(QString::fromUtf8(local_name.toAscii().constData()))
.arg(cnf->maddr)
.arg(QString::fromUtf8(remote_name.toAscii().constData())));
if (cnf->verbose) inst_dlg->displayCommand(args);
qApp->processEvents();
// Need session for scp copy because we need to enter password
runSSHSession( new SSHUnx(inst_dlg,
cnf->fwobj->getName().c_str(),
args,
cnf->pwd,
"",
list<string>()), true );
}
void FirewallInstaller::executeExternalInstallScript(const QString &command,

View File

@ -86,11 +86,12 @@ protected:
QString *remote_file_name,
bool *main_script);
bool readManifest(const QString &conffie, QMap<QString, QString> *all_files);
void executeExternalInstallScript(const QString &script,
const QString &script_args);
virtual bool readManifest(const QString &conffie,
QMap<QString, QString> *all_files);
public:
FirewallInstaller(instDialog *_dlg, instConf *_cnf, const QString &prompt)
@ -104,7 +105,7 @@ public:
void packSSHArgs(QStringList &args);
void packSCPArgs(const QString &local_name, const QString &remote_name, QStringList &args);
QString getActivationCmd();
QString getDestinationDir(const QString &dir);
virtual QString getDestinationDir(const QString &dir);
void terminate();

View File

@ -42,16 +42,23 @@
#include "fwbuilder/Management.h"
#include "fwbuilder/XMLTools.h"
#ifndef _WIN32
# include <unistd.h> // for access(2) and getdomainname
#endif
#include <QFileInfo>
#include <QTextStream>
#include <QMessageBox>
#include <QtDebug>
#include <errno.h>
#include <iostream>
using namespace std;
using namespace libfwbuilder;
FirewallInstallerCisco::FirewallInstallerCisco(instDialog *_dlg,
instConf *_cnf, const QString &_p):
FirewallInstaller(_dlg, _cnf, _p)
{
if (cnf->fwdir.isEmpty()) cnf->fwdir = "nvram:";
}
bool FirewallInstallerCisco::packInstallJobsList(Firewall*)
{
if (fwbdebug)
@ -72,7 +79,57 @@ bool FirewallInstallerCisco::packInstallJobsList(Firewall*)
return true;
}
job_list.push_back(instJob(ACTIVATE_POLICY, cnf->script, ""));
// Load configuration file early so we can abort installation if
// it is not accessible
QString ff;
QFileInfo script_info(cnf->script);
if (script_info.isAbsolute()) ff = cnf->script;
else ff = cnf->wdir + "/" + cnf->script;
QFile data(ff);
if (data.open(QFile::ReadOnly))
{
QTextStream strm(&data);
QString line;
do
{
line = strm.readLine();
config_lines.push_back(line.trimmed());
} while (!strm.atEnd());
} else
{
QMessageBox::critical(
inst_dlg, "Firewall Builder",
tr("Can not read generated script %1").arg(ff),
tr("&Continue"), QString::null,QString::null,
0, 1 );
return false;
}
// Should be optional
if (cnf->useSCPForCisco)
{
QMap<QString,QString> all_files;
// readManifest() modifies cnf (assigns cnf->remote_script) !
if (readManifest(cnf->script, &all_files))
{
QMap<QString, QString>::iterator it;
for (it=all_files.begin(); it!=all_files.end(); ++it)
{
QString local_name = it.key();
QString remote_name = it.value();
job_list.push_back(instJob(COPY_FILE, local_name, remote_name));
}
}
QString cmd = getActivationCmd();
job_list.push_back(instJob(ACTIVATE_POLICY, cmd, ""));
} else
{
job_list.push_back(instJob(ACTIVATE_POLICY, cnf->script, ""));
}
return true;
}
@ -157,9 +214,51 @@ void FirewallInstallerCisco::activatePolicy(const QString&, const QString&)
ssh_object->loadPostConfigCommands(
post_config.expand().split("\n", QString::SkipEmptyParts) );
Configlet activation(host_os, os_family, "installer_commands_reg_user");
activation.removeComments();
inst_dlg->replaceMacrosInCommand(&activation);
activation.setVariable("using_scp", cnf->useSCPForCisco);
activation.setVariable("not_using_scp", ! cnf->useSCPForCisco);
if ( ! cnf->useSCPForCisco)
{
activation.setVariable("fwbuilder_generated_configuration_lines",
config_lines.join("\n"));
}
ssh_object->loadActivationCommands(
activation.expand().split("\n", QString::SkipEmptyParts) );
runSSHSession(ssh_object);
return;
}
bool FirewallInstallerCisco::readManifest(const QString &script,
QMap<QString, QString> *all_files)
{
if (fwbdebug)
qDebug("FirewallInstaller::readManifest");
QString dest_dir = getDestinationDir(cnf->fwdir);
// path returned by getDestinationDir always ends with separator
// in case of IOS, it is ":"
QFileInfo file_base(script);
QString remote_file = dest_dir + file_base.fileName();
QString local_name = script;
cnf->remote_script = remote_file;
(*all_files)[local_name] = remote_file;
return true;
}
QString FirewallInstallerCisco::getDestinationDir(const QString &fwdir)
{
if (fwbdebug)
qDebug() << "FirewallInstallerCisco::getDestinationDir: "
<< "fwdir=" << fwdir;
QString dir = fwdir;
if (!dir.endsWith(":")) return dir + ":";
return dir;
}

View File

@ -36,6 +36,7 @@
#include <qstringlist.h>
#include <qprocess.h>
#include <qobject.h>
#include <QStringList>
namespace libfwbuilder
{
@ -44,12 +45,17 @@ namespace libfwbuilder
class FirewallInstallerCisco : public FirewallInstaller
{
Q_OBJECT
Q_OBJECT;
QStringList config_lines;
virtual QString getDestinationDir(const QString &dir);
virtual bool readManifest(const QString &conffie,
QMap<QString, QString> *all_files);
public:
FirewallInstallerCisco(instDialog *_dlg, instConf *_cnf, const QString &_p):
FirewallInstaller(_dlg, _cnf, _p) {}
FirewallInstallerCisco(instDialog *_dlg, instConf *_cnf, const QString &_p);
virtual bool packInstallJobsList(libfwbuilder::Firewall*);
virtual void activatePolicy(const QString &script, const QString &args);

View File

@ -189,34 +189,3 @@ void FirewallInstallerUnx::executeSession(const QString &cmd)
list<string>()), false );
}
// ************************************************************************
void FirewallInstallerUnx::copyFile(const QString &local_name,
const QString &remote_name)
{
QString platform = cnf->fwobj->getStr("platform").c_str();
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("latin1"));
QStringList args;
packSCPArgs(local_name, remote_name, args);
inst_dlg->addToLog( tr("Copying %1 -> %2:%3\n")
.arg(QString::fromUtf8(local_name.toAscii().constData()))
.arg(cnf->maddr)
.arg(QString::fromUtf8(remote_name.toAscii().constData())));
if (cnf->verbose) inst_dlg->displayCommand(args);
qApp->processEvents();
// Need session for scp copy because we need to enter password
runSSHSession( new SSHUnx(inst_dlg,
cnf->fwobj->getName().c_str(),
args,
cnf->pwd,
"",
list<string>()), true );
}
// ************************************************************************

View File

@ -53,7 +53,6 @@ public:
FirewallInstaller(_dlg, _cnf, _p) {}
virtual bool packInstallJobsList(libfwbuilder::Firewall*);
virtual void copyFile(const QString &local_name, const QString &remote_name);
virtual void activatePolicy(const QString &script, const QString &args);
};

View File

@ -27,16 +27,11 @@
#include "../../config.h"
#include "global.h"
#include "utils.h"
#include "SSHIOS.h"
#include <iostream>
#include <QtDebug>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
using namespace std;
@ -94,29 +89,30 @@ void SSHIOS::stateMachine()
switch (state)
{
case ENABLE:
if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) )
{
if (pre_config_commands.size()>0)
{
stdoutBuffer="";
// case ENABLE:
// if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) )
// {
// if (pre_config_commands.size()>0)
// {
// stdoutBuffer="";
QString cmd = pre_config_commands.front();
pre_config_commands.pop_front();
// QString cmd = pre_config_commands.front();
// pre_config_commands.pop_front();
if (cmd.indexOf("reload in")!=-1)
state = SCHEDULE_RELOAD_DIALOG;
// if (cmd.indexOf("reload in")!=-1)
// state = SCHEDULE_RELOAD_DIALOG;
proc->write( cmd.toAscii() );
proc->write( "\n" );
break;
} else
SSHPIX::stateMachine();
}
break;
// proc->write( cmd.toAscii() );
// proc->write( "\n" );
// break;
// } else
// SSHPIX::stateMachine();
// }
// break;
case SCHEDULE_RELOAD_DIALOG:
if ( cmpPrompt(stdoutBuffer,QRegExp("System config.* modified\\. Save?")) )
if ( cmpPrompt(stdoutBuffer,
QRegExp("System config.* modified\\. Save?")) )
{
stdoutBuffer="";
proc->write( "no\n" );
@ -131,6 +127,15 @@ void SSHIOS::stateMachine()
}
break;
case PUSHING_CONFIG:
if ( cmpPrompt(stdoutBuffer, QRegExp("Destination filename [.*]?")) )
{
stdoutBuffer="";
proc->write("\n"); // accept default file name
} else
SSHPIX::stateMachine();
break;
default:
SSHPIX::stateMachine();
break;

View File

@ -32,9 +32,11 @@
#include "SSHPIX.h"
#include <QString>
class SSHIOS : public SSHPIX {
Q_OBJECT
Q_OBJECT;
public:

View File

@ -59,6 +59,7 @@ SSHPIX::SSHPIX(QWidget *_par,
normal_prompt="> $";
fwb_prompt="--**--**--";
enable_prompt="# $|# *Access Rules Download Complete";
config_prompt="\\(config(|-.*)\\)#";
pwd_prompt_1="'s password: $";
pwd_prompt_2="'s password: $";
epwd_prompt="Password: ";
@ -99,6 +100,23 @@ void SSHPIX::loadPostConfigCommands(const QStringList &cl)
post_config_commands = cl;
}
void SSHPIX::loadActivationCommands(const QStringList &cl)
{
activation_commands = cl;
foreach(QString line, activation_commands)
{
/*
* store names of access-lists and object-groups
* actually used in the config
*/
if (line.indexOf("access-list ")==0)
newAcls.push_back(line.section(' ',1,1));
if (line.indexOf("object-group ")==0)
newObjectGroups.push_back(line.section(' ',1,1));
}
emit updateProgressBar_sign(activation_commands.size(), true);
}
SSHPIX::~SSHPIX()
{
}
@ -153,6 +171,12 @@ void SSHPIX::stateMachine()
{
if (checkForErrors()) return;
if (fwbdebug)
qDebug() << "SSHPIX::stateMachine() state=" << state
<< "(ENABLE=" << ENABLE << ")"
<< "(PUSHING_CONFIG=" << PUSHING_CONFIG << ")"
<< " stdoutBuffer=" << stdoutBuffer;
switch (state)
{
case NONE:
@ -162,13 +186,12 @@ void SSHPIX::stateMachine()
{
stdoutBuffer="";
proc->write( (pwd + "\n").toAscii() );
// proc->write( "\n" );
break;
}
/* we may get to LOGGEDIN state directly from NONE, for example when
* password is supplied on command line to plink.exe
*/
if (cmpPrompt(stdoutBuffer,QRegExp(normal_prompt)) )
if (cmpPrompt(stdoutBuffer, QRegExp(normal_prompt)) )
{
stdoutBuffer="";
state=LOGGEDIN;
@ -177,13 +200,12 @@ void SSHPIX::stateMachine()
emit printStdout_sign( tr("Switching to enable mode...") + "\n");
stdoutBuffer="";
proc->write( "enable\n" );
//proc->write( "\n" );
}
/* we may even get straight to the enable prompt, e.g. if
* user account is configured with "privilege 15"
*/
if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) )
if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) )
{
state=WAITING_FOR_ENABLE;
stateMachine();
@ -269,20 +291,15 @@ void SSHPIX::stateMachine()
}
case ENABLE:
if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) )
if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) )
{
if (pre_config_commands.size()>0)
{
stdoutBuffer="";
QString cmd = pre_config_commands.front();
pre_config_commands.pop_front();
if (cmd.indexOf("reload in")!=-1)
state = SCHEDULE_RELOAD_DIALOG;
if (cmd.indexOf("reload in")!=-1) state = SCHEDULE_RELOAD_DIALOG;
proc->write( (cmd + "\n").toAscii() );
// proc->write( "\n" );
break;
}
@ -303,26 +320,29 @@ void SSHPIX::stateMachine()
break;
}
proc->write( "config t\n" );
//proc->write( "\n" );
state=WAITING_FOR_CONFIG_PROMPT;
//proc->write( "config t\n" ); now part of configlet installer_commands_reg_user
state = WAITING_FOR_CONFIG_PROMPT;
// kick it so we get some output from the router and
// continue the state machine
proc->write("\n");
}
break;
case SCHEDULE_RELOAD_DIALOG:
if ( cmpPrompt(stdoutBuffer,QRegExp("System config.* modified\\. Save?")) )
if ( cmpPrompt(stdoutBuffer,
QRegExp("System config.* modified\\. Save?")) )
{
stdoutBuffer="";
proc->write( "n" ); // no \n needed
break;
}
if ( cmpPrompt(stdoutBuffer,QRegExp("Proceed with reload?")) )
if ( cmpPrompt(stdoutBuffer, QRegExp("Proceed with reload?")) )
{
stdoutBuffer="";
proc->write( "y" ); // no \n needed
break;
}
if ( cmpPrompt(stdoutBuffer,QRegExp("SHUTDOWN")) )
if ( cmpPrompt(stdoutBuffer, QRegExp("SHUTDOWN")) )
{
stdoutBuffer="";
proc->write( "\n" );
@ -343,88 +363,36 @@ void SSHPIX::stateMachine()
break;
case WAITING_FOR_CONFIG_PROMPT:
if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) )
if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt)) )
{
state=CONFIG;
/* install full policy */
QString ff;
QFileInfo script_info(script);
if (script_info.isAbsolute()) ff = script;
else ff = wdir + "/" + script;
config_file = new ifstream(ff.toLatin1().constData());
if ( ! *config_file)
{
emit printStdout_sign(
QObject::tr("Can not open file %1").arg(ff) + "\n"
);
state=FINISH;
break;
} else
{
/* read the whole file */
string s0;
nLines =0;
bool store=!incremental;
while ( !config_file->eof() )
{
getline( *config_file, s0);
if (!store)
{
store=(s0.find("!################")==0);
}
if (store)
{
QString s(s0.c_str());
s = s.trimmed();
allConfig.push_back(s);
nLines++;
/*
* store names of access-lists and object-groups actually used in the config
*/
if (s.indexOf("access-list ")==0)
newAcls.push_back(s.section(' ',1,1));
if (s.indexOf("object-group ")==0)
newObjectGroups.push_back(s.section(' ',1,1));
}
}
config_file->close();
delete config_file;
config_file=NULL;
emit updateProgressBar_sign(nLines,true);
}
state=PUSHING_CONFIG; // and drop to PUSHING_CONFIG case
/* install full policy */
state = PUSHING_CONFIG; // and drop to PUSHING_CONFIG case
if (!dry_run)
emit printStdout_sign(tr("Pushing firewall configuration"));
emit printStdout_sign( "\n");
stdoutBuffer = "";
proc->write("\n");
ncmd=0;
}
#if 0
else
{
/* install incrementally */
QTimer::singleShot( 1, this, SLOT(PIXincrementalInstall()) );
break;
}
#endif
break;
case PUSHING_CONFIG:
if ( cmpPrompt(stdoutBuffer,QRegExp(enable_prompt)) )
if ( cmpPrompt(stdoutBuffer, QRegExp(enable_prompt))) // config_prompt)) )
{
if (fwbdebug)
qDebug() << "SSHPIX::stateMachine() activation_commands.size()="
<< activation_commands.size();
loop1:
if ( allConfig.size()!=0 )
if ( activation_commands.size()!=0 )
{
QString s;
do {
s = allConfig.front();
allConfig.pop_front();
s = activation_commands.front();
activation_commands.pop_front();
} while (stripComments && s[0]=='!');
emit updateProgressBar_sign(allConfig.size(),false);
emit updateProgressBar_sign(activation_commands.size(),false);
s.replace('\"','\'');
@ -435,7 +403,6 @@ void SSHPIX::stateMachine()
if ( !rl.isEmpty())
{
emit printStdout_sign( tr("Rule %1").arg(rl) + "\n" );
//emit printStdout_sign( "\n");
}
}
@ -444,24 +411,21 @@ void SSHPIX::stateMachine()
if ( !s.isEmpty()) ncmd++;
stdoutBuffer="";
proc->write( (s+"\n").toAscii() ); // send even if s is empty
qApp->processEvents();
break;
} else
{
emit printStdout_sign( s+"\n" );
goto loop1;
}
break;
} else
{
/* allConfig.size()==0 */
// state=GET_ACLS;
// goto entry;
/* activation_commands.size()==0 */
state = EXIT_FROM_CONFIG;
emit printStdout_sign( tr("End") + "\n" );
proc->write( "exit\n" );
//proc->write( "exit\n" ); now part of the configlet
// kick it so we get some output from the router and
// continue the state machine
proc->write("\n");
}
}
break;
@ -709,112 +673,3 @@ void SSHPIX::clearObjectGroups()
proc->write( "exit\n" );
}
void SSHPIX::PIXincrementalInstall()
{
QString current_config;
bool sv=verbose;
verbose=false;
emit printStdout_sign(tr("Reading current firewall configuration"));
emit printStdout_sign( "\n");
current_config = cmd(proc, "show run | grep ^telnet|^ssh|^icmp");
if (state==FINISH) return;
current_config += cmd(proc, "show object-group");
if (state==FINISH) return;
current_config += cmd(proc, "show access-list");
if (state==FINISH) return;
current_config += cmd(proc, "show global");
if (state==FINISH) return;
current_config += cmd(proc, "show nat");
if (state==FINISH) return;
current_config += cmd(proc, "show static");
if (state==FINISH) return;
verbose=sv;
if (state==COMMAND_DONE)
{
QString statefile;
QFileInfo script_info(script);
if (script_info.isAbsolute()) statefile = script + "_current";
else statefile = wdir + "/" + script + "_current";
ofstream ofs(statefile.toLatin1().constData());
ofs << current_config.toAscii().constData();
ofs.close();
emit printStdout_sign(tr("Generating configuration diff"));
emit printStdout_sign( "\n");
QString cm = diff_pgm + " \"" + statefile + "\" \"";
if (script_info.isAbsolute()) cm += wdir + "/";
cm += script + "\"";
// emit printStdout_sign(tr("Running command: %1\n").arg(cm));
#ifdef _WIN32
FILE *f = _popen( cm.toLatin1().constData(), "r");
#else
FILE *f = popen( cm.toLatin1().constData(), "r");
#endif
if (f==NULL)
{
emit printStdout_sign(
tr("Fork failed for %1").arg(diff_pgm));
emit printStdout_sign( "\n");
switch (errno)
{
case EAGAIN:
case ENOMEM:
emit printStdout_sign(tr("Not enough memory.") + "\n");
break;
case EMFILE:
case ENFILE:
emit printStdout_sign(
tr("Too many opened file descriptors in the system.") + "\n");
break;
}
emit printStdout_sign( "\n");
state=FINISH;
proc->write( "\n" );
return;
}
char buf[1024];
int nLines=0;
while (fgets(buf,1024,f))
{
allConfig += buf;
nLines++;
}
#ifdef _WIN32
_pclose(f);
#else
pclose(f);
#endif
if (allConfig.isEmpty())
{
allConfig=QStringList();
emit printStdout_sign(tr("Empty configuration diff"));
emit printStdout_sign( "\n");
}
if (save_diff)
{
ofstream odiff((wdir+"/"+diff_file).toLatin1().constData());
odiff << allConfig.join("").toAscii().constData();
odiff.close();
}
state=PUSHING_CONFIG;
emit updateProgressBar_sign(nLines,true);
if (!dry_run)
emit printStdout_sign(tr("Pushing firewall configuration") + "\n");
}
proc->write( "\n" );
}

View File

@ -42,12 +42,12 @@ class QEventLoop;
class SSHPIX : public SSHSession {
Q_OBJECT
Q_OBJECT;
QEventLoop *local_event_loop;
int nLines;
int ncmd;
QStringList allConfig;
//QStringList allConfig;
QStringList newAcls;
QStringList currentAcls;
@ -55,11 +55,12 @@ class SSHPIX : public SSHSession {
QStringList newObjectGroups;
QStringList currentObjectGroups;
std::ifstream *config_file;
//std::ifstream *config_file;
protected:
QStringList pre_config_commands;
QStringList post_config_commands;
QStringList pre_config_commands;
QStringList post_config_commands;
QStringList activation_commands;
public:
@ -78,6 +79,7 @@ public:
void loadPreConfigCommands(const QStringList &cl);
void loadPostConfigCommands(const QStringList &cl);
void loadActivationCommands(const QStringList &cl);
public slots:
void PIXbackup();
@ -85,7 +87,6 @@ public slots:
void clearACLs();
void getObjectGroups();
void clearObjectGroups();
void PIXincrementalInstall();
};

View File

@ -118,6 +118,7 @@ class SSHSession : public QObject {
QString normal_prompt;
QString fwb_prompt;
QString enable_prompt;
QString config_prompt;
QString pwd_prompt_1;
QString pwd_prompt_2;
QString putty_pwd_prompt;

View File

@ -53,7 +53,8 @@ class instConf {
bool cancelRollbackIfSuccess;
bool saveStandby;
bool batchInstall;
bool useSCPForCisco;
QString pgm;
QString wdir;
QString diff_pgm;

View File

@ -322,6 +322,7 @@ void instDialog::storeInstallerOptions()
st->setValue(SETTINGS_PATH_PREFIX"/Installer/compressScript",
cnf.compressScript);
st->setValue(SETTINGS_PATH_PREFIX"/Installer/copyFWB", cnf.copyFWB);
st->setValue(SETTINGS_PATH_PREFIX"/Installer/useSCPForCisco", cnf.useSCPForCisco);
st->setValue(SETTINGS_PATH_PREFIX"/Installer/testRun", cnf.testRun);
st->setValue(SETTINGS_PATH_PREFIX"/Installer/rollback", cnf.rollback);
st->setValue(SETTINGS_PATH_PREFIX"/Installer/rollbackTime",
@ -535,8 +536,8 @@ void instDialog::saveLog()
*/
void instDialog::addToLog(const QString &line)
{
if (fwbdebug)
qDebug("instDialog::addToLog: '%s'", line.toLatin1().constData());
// if (fwbdebug)
// qDebug("instDialog::addToLog: '%s'", line.toLatin1().constData());
if (line.isEmpty()) return;
@ -921,6 +922,7 @@ void instDialog::readInstallerOptionsFromSettings()
cnf.stripComments = st->value(SETTINGS_PATH_PREFIX"/Installer/stripComments").toBool();
cnf.compressScript = st->value(SETTINGS_PATH_PREFIX"/Installer/compressScript").toBool();
cnf.copyFWB = st->value(SETTINGS_PATH_PREFIX"/Installer/copyFWB").toBool();
cnf.useSCPForCisco = st->value(SETTINGS_PATH_PREFIX"/Installer/useSCPForCisco").toBool();
cnf.testRun = st->value(SETTINGS_PATH_PREFIX"/Installer/testRun").toBool();
cnf.rollback = st->value(SETTINGS_PATH_PREFIX"/Installer/rollback").toBool();
cnf.rollbackTime = st->value(SETTINGS_PATH_PREFIX"/Installer/rollbackTime").toInt();
@ -1054,6 +1056,7 @@ void instDialog::readInstallerOptionsFromDialog(Firewall *fw,
cnf.stripComments = dlg->m_dialog->stripComments->isChecked();
cnf.compressScript= dlg->m_dialog->compressScript->isChecked();
cnf.copyFWB = dlg->m_dialog->copyFWB->isChecked();
cnf.useSCPForCisco= dlg->m_dialog->use_scp->isChecked();
cnf.testRun = dlg->m_dialog->testRun->isChecked();
cnf.rollback = dlg->m_dialog->rollback->isChecked();
cnf.rollbackTime = dlg->m_dialog->rollbackTime->value();

View File

@ -94,6 +94,7 @@ instOptionsDialog::instOptionsDialog(QWidget *parent, instConf *_cnf) :
m_dialog->stripComments->setChecked( cnf->stripComments );
m_dialog->compressScript->setChecked( cnf->compressScript );
m_dialog->copyFWB->setChecked( cnf->copyFWB );
m_dialog->use_scp->setChecked( cnf->useSCPForCisco );
m_dialog->testRun->setChecked( cnf->testRun );
m_dialog->rollback->setChecked( cnf->rollback );
m_dialog->rollbackTime->setValue( cnf->rollbackTime );
@ -145,6 +146,7 @@ instOptionsDialog::instOptionsDialog(QWidget *parent, instConf *_cnf) :
}
}
if (platform=="iosacl") m_dialog->PIXgroupBox->hide();
else m_dialog->IOSgroupBox->hide();
} else
{
m_dialog->rollback->setText("Schedule reboot in ");
@ -153,6 +155,7 @@ instOptionsDialog::instOptionsDialog(QWidget *parent, instConf *_cnf) :
m_dialog->epwd->hide();
m_dialog->epwdLbl->hide();
m_dialog->PIXgroupBox->hide();
m_dialog->IOSgroupBox->hide();
// cancelling rollback at the end of activation is currently
// only supported on pix,fwsm and ios
m_dialog->cancelRollbackIfSuccess->hide();

View File

@ -5,8 +5,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>588</width>
<height>759</height>
<width>732</width>
<height>978</height>
</rect>
</property>
<property name="sizePolicy" >
@ -30,10 +30,7 @@
<property name="sizeGripEnabled" >
<bool>false</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>4</number>
</property>
<layout class="QGridLayout" name="gridLayout_4" >
<item row="0" column="0" >
<widget class="QFrame" name="titleFrame" >
<property name="sizePolicy" >
@ -68,60 +65,6 @@
</layout>
</widget>
</item>
<item row="2" column="0" >
<widget class="QFrame" name="buttonsFrame" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>32767</width>
<height>32767</height>
</size>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" >
<item row="0" column="1" >
<widget class="QPushButton" name="okButton" >
<property name="text" >
<string>OK</string>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QPushButton" name="cancelButton" >
<property name="text" >
<string>Cancel</string>
</property>
</widget>
</item>
<item row="0" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>230</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" >
<widget class="QFrame" name="mainBox" >
<property name="sizePolicy" >
@ -136,8 +79,296 @@
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" >
<layout class="QGridLayout" name="gridLayout_3" >
<item row="0" column="0" colspan="2" >
<widget class="QFrame" name="frame15" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>500</width>
<height>50</height>
</size>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="unameLbl" >
<property name="text" >
<string>User name:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="uname" />
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>22</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="pwdLbl" >
<property name="text" >
<string>Password or passphrase:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="pwd" />
</item>
<item row="2" column="0" >
<widget class="QLabel" name="epwdLbl" >
<property name="text" >
<string>Enable password:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="epwd" />
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="rememberPass" >
<property name="toolTip" >
<string>Enable password caching for the duration of the session (passwords
are never stored permanently)</string>
</property>
<property name="layoutDirection" >
<enum>Qt::LeftToRight</enum>
</property>
<property name="text" >
<string>Remember passwords</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2" >
<widget class="QGroupBox" name="PIXgroupBox" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title" >
<string/>
</property>
<property name="flat" >
<bool>false</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>12</number>
</property>
<item row="5" column="0" colspan="2" >
<widget class="QCheckBox" name="saveStandby" >
<property name="text" >
<string>Write configuration to standby PIX</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2" >
<widget class="QCheckBox" name="test" >
<property name="text" >
<string>Dry run (commands won't be executed on the firewall)</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QCheckBox" name="saveDiff" >
<property name="text" >
<string>Store configuration diff in a file</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2" >
<widget class="QCheckBox" name="incr" >
<property name="toolTip" >
<string>Calculate difference between current firewall state and generated configuration and install only those commands that update state of the firewall</string>
</property>
<property name="text" >
<string>install only ACL, 'icmp', 'telnet', 'ssh', 'nat', 'global' and 'static' commands</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="backupConfigFileLbl" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Make a backup copy of the firewall configuration in this file:</string>
</property>
<property name="alignment" >
<set>Qt::AlignVCenter</set>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="backupConfigFile" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2" >
<widget class="QGroupBox" name="IOSgroupBox" >
<property name="title" >
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2" >
<item row="0" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Instead of running generated configuration on the router line by line, installer can use scp to copy the file to the router and then "copy file running-config" command to activate it. Ssh v2 and scp servers should be configured on the router for this to work. This method is much faster than running configuration line by line.</string>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="use_scp" >
<property name="text" >
<string>Copy IOS configuration file to the router using scp</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="altAddressLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Address that will be used to communicate with the firewall:</string>
</property>
<property name="alignment" >
<set>Qt::AlignVCenter</set>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="altAddress" >
<property name="minimumSize" >
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>32767</width>
<height>32767</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2" >
<widget class="QFrame" name="generalOptionsBox" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QCheckBox" name="quiet" >
<property name="text" >
<string>Quiet install: do not print anything as commands are executed on the firewall</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="verbose" >
<property name="text" >
<string>Verbose: print all commands as they are executed on the firewall</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QCheckBox" name="stripComments" >
<property name="text" >
<string>Remove comments from configuration</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="compressScript" >
<property name="text" >
<string>Compress script</string>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QCheckBox" name="copyFWB" >
<property name="text" >
<string>Store a copy of fwb file on the firewall</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0" colspan="2" >
<widget class="QFrame" name="testOptionsBox" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
@ -241,267 +472,72 @@
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QFrame" name="generalOptionsBox" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="6" column="0" colspan="2" >
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
<property name="sizeHint" stdset="0" >
<size>
<width>568</width>
<height>28</height>
</size>
</property>
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QCheckBox" name="quiet" >
<property name="text" >
<string>Quiet install: do not print anything as commands are executed on the firewall</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="verbose" >
<property name="text" >
<string>Verbose: print all commands as they are executed on the firewall</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QCheckBox" name="stripComments" >
<property name="text" >
<string>Remove comments from configuration</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="compressScript" >
<property name="text" >
<string>Compress script</string>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QCheckBox" name="copyFWB" >
<property name="text" >
<string>Store a copy of fwb file on the firewall</string>
</property>
</widget>
</item>
</layout>
</widget>
</spacer>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="altAddressLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</layout>
</widget>
</item>
<item row="2" column="0" >
<widget class="QFrame" name="buttonsFrame" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>32767</width>
<height>32767</height>
</size>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" >
<item row="0" column="1" >
<widget class="QPushButton" name="okButton" >
<property name="text" >
<string>Address that will be used to communicate with the firewall:</string>
</property>
<property name="alignment" >
<set>Qt::AlignVCenter</set>
</property>
<property name="wordWrap" >
<bool>true</bool>
<string>OK</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="altAddress" >
<property name="minimumSize" >
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>32767</width>
<height>32767</height>
</size>
<item row="0" column="2" >
<widget class="QPushButton" name="cancelButton" >
<property name="text" >
<string>Cancel</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2" >
<widget class="QGroupBox" name="PIXgroupBox" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<item row="0" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="title" >
<string/>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="flat" >
<bool>false</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>12</number>
</property>
<item row="5" column="0" colspan="2" >
<widget class="QCheckBox" name="saveStandby" >
<property name="text" >
<string>Write configuration to standby PIX</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2" >
<widget class="QCheckBox" name="test" >
<property name="text" >
<string>Dry run (commands won't be executed on the firewall)</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" >
<widget class="QCheckBox" name="saveDiff" >
<property name="text" >
<string>Store configuration diff in a file</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2" >
<widget class="QCheckBox" name="incr" >
<property name="toolTip" >
<string>Calculate difference between current firewall state and generated configuration and install only those commands that update state of the firewall</string>
</property>
<property name="text" >
<string>install only ACL, 'icmp', 'telnet', 'ssh', 'nat', 'global' and 'static' commands</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="backupConfigFileLbl" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>Make a backup copy of the firewall configuration in this file:</string>
</property>
<property name="alignment" >
<set>Qt::AlignVCenter</set>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="backupConfigFile" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" colspan="2" >
<widget class="QFrame" name="frame15" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<property name="sizeHint" stdset="0" >
<size>
<width>500</width>
<height>50</height>
<width>230</width>
<height>20</height>
</size>
</property>
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="unameLbl" >
<property name="text" >
<string>User name:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="uname" />
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>22</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="pwdLbl" >
<property name="text" >
<string>Password or passphrase:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="pwd" />
</item>
<item row="2" column="0" >
<widget class="QLabel" name="epwdLbl" >
<property name="text" >
<string>Enable password:</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="epwd" />
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="rememberPass" >
<property name="toolTip" >
<string>Enable password caching for the duration of the session (passwords
are never stored permanently)</string>
</property>
<property name="layoutDirection" >
<enum>Qt::LeftToRight</enum>
</property>
<property name="text" >
<string>Remember passwords</string>
</property>
</widget>
</item>
</layout>
</widget>
</spacer>
</item>
</layout>
</widget>

View File

@ -0,0 +1,28 @@
## -*- mode: shell-script; -*-
##
## Lines that start with "##" will be removed before this code is
## added to the generated script. Regular shell comments can be added
## using single "#", these will appear in the script.
##
##
## These are commands built-in policy installer runs on the firewall if
## installation is performed using regular user account for authentication
##
## Variables:
##
## {{$fwbprompt}} -- "magic" prompt that installer uses to detect when it is logged in
## {{$fwdir}} -- directory on the firewall
## {{$fwscript}} -- script name on the firewall (including directory. "nvram:" for IOS)
## {{$rbtimeout}} -- rollback timeout
## {{$rbtimeout_sec}} -- rollback timeout (sec)
##
{{if using_scp}}
copy {{$fwscript}} running-config
{{endif}}
{{if not_using_scp}}
config term
{{$fwbuilder_generated_configuration_lines}}
exit
{{endif}}

View File

@ -676,6 +676,15 @@ rule sets of this object rather than in the actual firewalls.
<a name="ios"></a>
<h2>Changes in support for for Cisco IOS ACL</h2>
<p>
Built-in installer can use command scp to copy IOS configuration to
the router using ssh and then command "copy file running-config" to
activate it. This method is much faster than running configuration
line by line. The router should be configured with ssh v2 and scp
server. This method can be combined with rollback (by reload or
EEM).
</p>
<p>
Built-in policy installe uses EEM (Embedded Event Manager) on IOS 12.4
or later to schedule automatic configuration rollback instead of