1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2010 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@fwbuilder.org
8 
9   $Id$
10 
11   This program is free software which we release under the GNU General Public
12   License. You may redistribute and/or modify this program under the terms
13   of that license as published by the Free Software Foundation; either
14   version 2 of the License, or (at your option) any later version.
15 
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20 
21   To get a copy of the GNU General Public License, write to the Free Software
22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 
24 */
25 
26 #include "config.h"
27 #include "global.h"
28 #include "utils.h"
29 #include "utils_no_qt.h"
30 
31 #include "FirewallInstallerProcurve.h"
32 #include "instDialog.h"
33 #include "SSHPIX.h"
34 #include "SSHIOS.h"
35 #include "SSHProcurve.h"
36 
37 #include "Configlet.h"
38 
39 #include "fwbuilder/Resources.h"
40 #include "fwbuilder/FWObjectDatabase.h"
41 #include "fwbuilder/Firewall.h"
42 #include "fwbuilder/XMLTools.h"
43 #include "fwbuilder/Interface.h"
44 #include "fwbuilder/Management.h"
45 #include "fwbuilder/XMLTools.h"
46 
47 #include <QFileInfo>
48 #include <QTextStream>
49 #include <QMessageBox>
50 #include <QtDebug>
51 
52 
53 using namespace std;
54 using namespace libfwbuilder;
55 
56 
FirewallInstallerProcurve(instDialog * _dlg,instConf * _cnf,const QString & _p)57 FirewallInstallerProcurve::FirewallInstallerProcurve(instDialog *_dlg,
58                                                      instConf *_cnf, const QString &_p):
59     FirewallInstallerCisco(_dlg, _cnf, _p)
60 {
61 }
62 
packInstallJobsList(Firewall *)63 bool FirewallInstallerProcurve::packInstallJobsList(Firewall*)
64 {
65     if (fwbdebug)
66         qDebug("FirewallInstallerProcurve::packInstallJobList  script=%s",
67        #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
68                cnf->script.toAscii().constData());
69        #else
70                cnf->script.toLatin1().constData());
71        #endif
72     job_list.clear();
73 
74     Management *mgmt = cnf->fwobj->getManagementObject();
75     assert(mgmt!=NULL);
76     PolicyInstallScript *pis = mgmt->getPolicyInstallScript();
77     if (pis->getCommand()!="")
78     {
79         QString cmd = pis->getCommand().c_str();
80         QString args = pis->getArguments().c_str();
81         job_list.push_back(
82             instJob(RUN_EXTERNAL_SCRIPT, cmd, args));
83         inst_dlg->addToLog(QString("Run script %1 %2\n").arg(cmd).arg(args));
84         return true;
85     }
86 
87     // Load configuration file early so we can abort installation if
88     // it is not accessible
89 
90     QString ff;
91     QFileInfo script_info(cnf->script);
92     if (script_info.isAbsolute()) ff = cnf->script;
93     else ff = cnf->wdir + "/" + cnf->script;
94 
95     QFile data(ff);
96     if (data.open(QFile::ReadOnly))
97     {
98         QTextStream strm(&data);
99         QString line;
100         do
101         {
102             line = strm.readLine();
103             config_lines.push_back(line.trimmed());
104         } while (!strm.atEnd());
105     } else
106     {
107         QMessageBox::critical(
108             inst_dlg, "Firewall Builder",
109             tr("Can not read generated script %1").arg(ff),
110             tr("&Continue"), QString::null,QString::null,
111             0, 1 );
112         return false;
113     }
114 
115 #ifdef SCP_SUPPORT_FOR_PROCURVE
116 
117     if (cnf->useSCPForRouter)
118     {
119         QMap<QString,QString> all_files;
120 
121         // readManifest() modifies cnf (assigns cnf->remote_script) !
122         if (readManifest(cnf->script, &all_files))
123         {
124             QMap<QString, QString>::iterator it;
125             for (it=all_files.begin(); it!=all_files.end(); ++it)
126             {
127                 QString local_name = it.key();
128                 QString remote_name = it.value();
129                 job_list.push_back(instJob(COPY_FILE, local_name, remote_name));
130             }
131         }
132 
133         QString cmd = getActivationCmd();
134         job_list.push_back(instJob(ACTIVATE_POLICY, cmd, ""));
135     } else
136     {
137         job_list.push_back(instJob(ACTIVATE_POLICY, cnf->script, ""));
138     }
139 
140 #endif
141 
142     job_list.push_back(instJob(ACTIVATE_POLICY, cnf->script, ""));
143 
144     return true;
145 }
146 
activatePolicy(const QString &,const QString &)147 void FirewallInstallerProcurve::activatePolicy(const QString&, const QString&)
148 {
149     QStringList args;
150 
151     packSSHArgs(args);
152     if (cnf->verbose) inst_dlg->displayCommand(args);
153 
154     SSHProcurve *ssh_object = NULL;
155     ssh_object = new SSHProcurve(inst_dlg,
156                                  cnf->fwobj->getName().c_str(),
157                                  args,
158                                  cnf->pwd,
159                                  cnf->epwd,
160                                  list<string>());
161 
162     /*
163      * TODO:
164      * the structure of scriptlets (command templates) for PIX and
165      * IOS is nice and generic, it uses generalized "pre_config"
166      * and "post_config" hooks in SSHPIX / SSHIOS classes. Need to
167      * do the same for Unix firewalls.
168      */
169 
170     QString cmd = "";
171     QStringList pre_config_commands;
172     QStringList post_config_commands;
173 
174     string version = cnf->fwobj->getStr("version");
175 
176     string host_os = cnf->fwobj->getStr("host_OS");
177     string os_family = Resources::os_res[host_os]->
178         getResourceStr("/FWBuilderResources/Target/family");
179 
180     // installer configlets should be different for each OS, but if
181     // some OS can use the same script, it will be placed in the file
182     // under os_family name. For example:
183     // for PIX configlet is in src/res/configlets/pix_os
184     // but since fwsm and pix can use the same script and fwsm_os.xml
185     // declares family as "pix_os", it uses the same configlet.
186 
187     Configlet pre_config(host_os, os_family, "installer_commands_pre_config");
188     pre_config.removeComments();
189 
190     // test run and rollback were deprecated in 4.2.0. On Linux, BSD
191     // and PIX rollback was implemented by rebooting firewall which is
192     // too heavy-handed and it did not work on BSD at all.
193     pre_config.setVariable("test", false);
194     pre_config.setVariable("run", true);
195     pre_config.setVariable("schedule_rollback", false);
196     pre_config.setVariable("cancel_rollback", false);
197 
198     pre_config.setVariable("save_standby", cnf->saveStandby);
199 
200     replaceMacrosInCommand(&pre_config);
201 
202     Configlet post_config(host_os, os_family, "installer_commands_post_config");
203     post_config.removeComments();
204 
205     post_config.setVariable("test", false);
206     post_config.setVariable("run", true);
207     post_config.setVariable("schedule_rollback", false);
208     post_config.setVariable("cancel_rollback", false);
209 
210     post_config.setVariable("save_standby", cnf->saveStandby);
211 
212     replaceMacrosInCommand(&post_config);
213 
214     ssh_object->loadPreConfigCommands(
215         pre_config.expand().split("\n", QString::SkipEmptyParts) );
216 
217     ssh_object->loadPostConfigCommands(
218         post_config.expand().split("\n", QString::SkipEmptyParts) );
219 
220     Configlet activation(host_os, os_family, "installer_commands_reg_user");
221     activation.removeComments();
222 
223     replaceMacrosInCommand(&activation);
224 
225     activation.setVariable("using_scp",     false);
226     activation.setVariable("not_using_scp", true);
227 
228     if ( ! cnf->useSCPForRouter)
229     {
230         activation.setVariable("fwbuilder_generated_configuration_lines",
231                                config_lines.join("\n"));
232     }
233 
234     ssh_object->loadActivationCommands(
235         activation.expand().split("\n", QString::SkipEmptyParts) );
236 
237     runSSHSession(ssh_object);
238 
239     return;
240 }
241 
242